简体   繁体   English

在多个数据库表上按日期进行计数和分组

[英]Count and group by date on multiple database tables

Working on a report page that contains counts for certain columns from the last 10 ten days I got this to work in c# after multiple queries to the database but ran in to trouble on the date columns so I figured I'd try and write a stored procedure or a single query that returned all the results I needed but I've stressed myself enough and I'm not a SQL guru (this is not homework btw!) 在一个报表页面上工作,该页面包含最近十天中某些列的计数,在对数据库进行多次查询后,我在C#中运行了该列,但是在日期列上遇到了麻烦,因此我想尝试编写一个存储过程或单个查询返回了我需要的所有结果,但是我已经足够强调自己了,而且我不是SQL专家(这不是家庭作业!)

I have 2 different tables in different databases that only have the date in (common) (sort -of) but the column names are different. 我在不同的数据库中有2个不同的表,它们的日期只有(普通)(排序-of),但列名却不同。

db1.order  
-----------  
c1    c2      c3      requestedshipping    dateadded
------------------------------------------------------
1    1.00    .95      ground            2013-05-15 18:34:48.867<-has time stamp in date
2    1.50    1.56     express           2013-05-15 18:34:48.867
3    .50     75       ground            2013-05-14 18:34:48.867
4    .50     75       ground            2013-05-14 18:34:48.867

db2.ship
-----------  
c1    c2         service               dateshipped
------------------------------------------------------
.25    1.00      ground            2013-05-15 00:00:00<-time stamp ?
2.3    1.50      express           2013-05-15 00:00:00
.36    .50       ground            2013-05-14 00:00:00

Trying to get results like 试图获得类似的结果

date       tot_order  tot_shipped  tot_express  tot_order_c3   tot_ship_c1   tot_ship_c2
--------------------------------------------------------------------------------------
2013-05-15   2           2            1           2.51           2.28          2.50
2013-05-14   2           1            0           150            .36           .50

THINGS I'VE TRIED I was using these queries to get totals then comparing the dates in c# but with the time stamp numbers weren't matching up 我尝试过的事情我正在使用这些查询来获取总数,然后比较c#中的日期,但时间戳数不匹配

SELECT TOP (10) DATEADD(dd, DATEDIFF(dd, 0, db1order.dateadded), 0) od,   COUNT(db1order.dateadded)
   FROM [db1].[dbo].[order] db1order 
   GROUP BY DATEADD(dd, DATEDIFF(dd, 0, db1order.dateadded), 0) 
   ORDER BY od DESC 



SELECT TOP (10) DATEADD(dd, DATEDIFF(dd, 0, db2ship.dateshipped), 0) od,   COUNT(db2ship.dateshipped)
   FROM [db2].[dbo].[ship] db2ship 
   GROUP BY DATEADD(dd, DATEDIFF(dd, 0, db2ship.dateshipped), 0) 
   ORDER BY od DESC 

I saw a article about using UNION ALL but this unions the totals together. 我看到了一篇有关使用UNION ALL的文章,但这将总和结合在一起。

select TOP (10) dt, count(*)
   from (select DATEADD(dd, DATEDIFF(dd, 0, dateadded), 0) AS dt from [db1].[dbo].   [order] union all
      select DATEADD(dd, DATEDIFF(dd, 0, dateshipped), 0) AS dt from [db2].[dbo].[ship]) v
group by dt
ORDER BY dt DESC 

I seen a couple of articles about creating a temp table but no examples of how to get information like I want into the table. 我看过几篇有关创建临时表的文章,但没有关于如何在表中获取所需信息的示例。

You can union the results of the two tables in the same format within a Common Table Expression http://technet.microsoft.com/en-us/library/ms190766(v=sql.105).aspx (aka CTE) , and add a "rowType" column to allow you to differentiate between an order vs. a ship row, and then perform your aggregates based on this. 您可以在通用表表达式http://technet.microsoft.com/zh-cn/library/ms190766(v = sql.105) .aspx (又称为CTE)中以相同格式合并两个表的结果。添加“ rowType”列,以使您可以区分order行与ship行,然后基于此行进行汇总。

;WITH cteCombined as
(
    SELECT 
          rowType = 0 --orders
        , [date] = convert(date, o.dateadded) 
        , o.c1
        , o.c2
        , o.c3
        , o.requestedshipping
    FROM [db1].[dbo].[order] o 
    UNION ALL
    SELECT 
          rowType = 1 --shipments
        , [date] = convert(date, s.dateshipped)
        , s.c1, s.c2
        , c3 = null
        , requestedshipping = s.[service]
    FROM [db2].[dbo].[ship] s
)
SELECT c.[date]
    , tot_order = sum(case when c.rowtype = 0 then 1 else 0 end)
    , tot_shipped = sum(case when c.rowtype = 1 then 1 else 0 end)
    --EDIT: based on expected results then tot_express appears to be only based on orders (with assumption that you will have an order prior to a shipment)
    , tot_express = sum(case when c.rowType = 0 AND c.requestedshipping = 'EXPRESS' then 1 else 0 end)
    , tot_order_c3 =  sum(case when c.rowtype = 0 then c.c3 else 0 end)
    , tot_ship_c1 =  sum(case when c.rowtype = 1 then c.c1 else 0 end)
    , tot_ship_c2 =  sum(case when c.rowtype = 1 then c.c2 else 0 end)
    /*etc...*/
FROM cteCombined c
GROUP BY c.[date]
;

You could use two CTEs, one for the orders and one for the shipments, and then join the two. 您可以使用两个CTE,一个用于订单,一个用于货运,然后将两者合并。 I wasn't sure how you wanted to handle express though -- where does that value come from? 我不确定您想如何处理express -该价值来自何处? In the example below, I used the service column from the shipments table, not the orders table, because based on your example you're only summing one of them. 在下面的示例中,我使用了出货表中的服务列,而不是订单表中的列,因为根据您的示例,您仅对其中之一进行求和。

See sqlFiddle 参见sqlFiddle

;with orders AS (
  SELECT CAST(dateadded AS DATE) as [date],
        COUNT(*) AS tot_order, 
        SUM(o.c3) AS tot_order_c3
  FROM tblOrder o
  GROUP BY CAST(dateadded AS DATE)
),
shipments AS (
  SELECT CAST(dateshipped AS DATE) as [date],
         COUNT(*) AS tot_shipped,
         SUM(CASE WHEN service = 'express' THEN 1 ELSE 0 END) AS tot_express,
         SUM(c1) AS tot_ship_c1,
         SUM(c2) AS tot_ship_c2
  FROM tblShip
  GROUP BY CAST(dateshipped AS DATE)
)
SELECT ISNULL(s.[date], o.[date]) as [date],
       ISNULL(o.tot_order, 0) as tot_order,
       ISNULL(s.tot_shipped, 0) as tot_shipped,
       ISNULL(s.tot_express, 0) as tot_express,
       ISNULL(o.tot_order_c3, 0) as tot_order_c3,
       ISNULL(s.tot_ship_c1, 0) as tot_ship_c1,
       ISNULL(s.tot_ship_c2, 0) as tot_ship_c2
FROM shipments s
FULL JOIN orders o ON s.[date] = o.[date]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM