按位置按日期显示订单活动

时间:2015-04-24 02:01:03

标签: sql-server tsql

编辑:为不包含更好的样本数据而道歉。

寻找SQL查询的一些帮助,以按日期和位置报告销售活动。目的是按日期和地点查看收到的订单数量,履行的订单数量,以及仍需要履行的订单数量。

表格格式

Order_ID,Location,Customer,Order_Placed_at,Order_fulfilled_at
1,A,Cust 1,1/1/2015 12:45,1/5/2015 13:00
2,B,Cust 2,1/5/2015 17:00,NULL
3,A,Cust 3,1/4/2015 14:00,1/6/2015 14:00
4,B,Cust 4,1/2/2015 14:00,1/3/2015 14:00
5,A,Cust 5,1/5/2015 18:00,1/6/2015 6:00
6,A,Cust 6,1/3/2015 14:00,1/6/2015 14:00
7,B,Cust 7,1/7/2015 14:00,1/8/2015 14:00
8,A,Cust 8,1/8/2015 14:00,NULL

期望的结果

Date,Location,Orders Placed,Orders Fulfilled,Unfulfilled_orders
12/31/2014,A,0,0,0
12/31/2014,B,0,0,0
1/1/2015,A,1,0,1
1/1/2015,B,0,0,0
1/2/2015,A,0,0,1
1/2/2015,B,1,0,1
1/3/2015,A,1,0,2
1/3/2015,B,0,1,0
1/4/2015,A,1,0,3
1/4/2015,B,0,0,0
1/5/2015,A,1,1,3
1/5/2015,B,1,0,1
1/6/2015,A,0,3,0
1/6/2015,B,0,0,0
1/7/2015,A,0,0,0
1/7/2015,B,1,0,1
1/8/2015,A,1,0,1
1/8/2015,B,0,1,0
1/9/2015,A,0,0,1
1/9/2015,B,0,0,0

我可以单独查询三个计数列,但我很难找到一种方法在一个结果集中返回它。特别是当我试图包括我的表中不存在的日期时,例如2015年9月1日。

select date, location, count(*) as Unfulfilled_orders
from [TABLE]
where order_placed <= '01/02/2015' and order_fulfilled_at is null)
group by date, location

1 个答案:

答案 0 :(得分:1)

1.您想要的结果与提供的数据样本相关

2.要每天跟踪所需数据,您需要在服务器上保留日历表,或者如下例所示

所以,我的解决方案的变体

--Create temp table for OP sample data

IF OBJECT_ID('Tempdb..#yourdata') IS NOT NULL 
    DROP TABLE #yourdata
SELECT  *
INTO    #yourdata
FROM    ( VALUES ( 1, 'A', 'Cust 1', '2015-01-01 12:45', '2015-01-05 13:00'),
        ( 2, 'B', 'Cust 2', '2015-01-05 17:00', NULL),
        ( 3, 'A', 'Cust 3', '2015-01-04 14:00', '2015-01-06 14:00'),
        ( 4, 'B', 'Cust 4', '2015-01-02 14:00', '2015-01-03 14:00'),
        ( 5, 'A', 'Cust 5', '2015-01-05 18:00', '2015-01-06 6:00'),
        ( 6, 'A', 'Cust 6', '2015-01-03 14:00', '2015-01-06 14:00'),
        ( 7, 'B', 'Cust 7', '2015-01-07 14:00', '2015-01-08 14:00'),
        ( 8, 'A', 'Cust 8', '2015-01-08 14:00', NULL) ) AS T ( Order_ID, Location, Customer, Order_Placed_at, Order_fulfilled_at ) 

--Create temp table for calendar with locations

IF OBJECT_ID('Tempdb..#calendar') IS NOT NULL 
    DROP TABLE #calendar;
WITH    cte
          AS ( SELECT   CONVERT(DATE, '20141231') AS [Dt]
               UNION ALL
               SELECT   DATEADD(DAY, 1, Dt)
               FROM     cte
               WHERE    dt < CONVERT(DATE, '20160101')
             )
    SELECT  A.Dt ,
            B.Location
    INTO    #calendar
    FROM    cte AS A
            CROSS JOIN ( SELECT *
                         FROM   ( VALUES ( 'A'), ( 'B') ) AS B ( Location ) 
                       ) AS B
OPTION  ( MAXRECURSION 366 )


--final query

SELECT  C.Location ,
        C.Dt ,
        COUNT(Y.Order_ID) AS [Orders Placed] ,
        COUNT(Y.Order_fulfilled_at) AS [Orders Fulfilled] ,
        COUNT(Y.Order_ID) - COUNT(Y.Order_fulfilled_at) AS [Unfulfilled orders]
FROM    #calendar AS C
        LEFT JOIN #yourdata AS Y ON C.Dt = CONVERT(DATE, Y.Order_Placed_at)
                                    AND C.Location = Y.Location
WHERE   C.Dt BETWEEN '20141231' AND '20150109'
GROUP BY C.Location ,
        C.Dt
ORDER BY C.Dt ,
        C.Location

输出结果

enter image description here