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

时间:2014-05-02 20:52:00

标签: sql sql-server tsql

处理一个报告页面,其中包含过去10天内某些列的计数我在对数据库进行多次查询后在c#中工作但在日期列中遇到了麻烦所以我认为我是尝试编写一个存储过程或单个查询,返回我需要的所有结果,但我已经足够强调自己了,我不是一个SQL大师(这不是作业顺便说一句!)

我在不同数据库中有2个不同的表,只有日期(普通)(sort -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

尝试获得像

这样的结果
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

我做过的尝试 我使用这些查询得到总数然后比较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 

我看到一篇关于使用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 

我看过几篇关于创建临时表的文章,但没有关于如何在表中获取我想要的信息的示例。

2 个答案:

答案 0 :(得分:1)

您可以在公用表表达式http://technet.microsoft.com/en-us/library/ms190766(v=sql.105).aspx(a.k.a. CTE)中以相同的格式将两个表的结果合并,并添加&#34; rowType&#34;列,以便您区分ordership行,然后根据此行执行聚合。

;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]
;

答案 1 :(得分:0)

您可以使用两个CTE,一个用于订单,一个用于货件,然后加入两个。我不确定你想如何处理express - 这个价值来自哪里?在下面的示例中,我使用了货运表中的服务列,而不是订单表,因为根据您的示例,您只需将其中一个汇总。

请参阅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]