获取日期差异然后在

时间:2018-04-16 14:10:31

标签: sql-server tsql aggregate-functions

我们要做的是准确表示一个月内的典型订单量。 每个下个月(包括订单开放的月份)在该订单关闭之前将对该订单计数为1。 因此对于例如2017年2月创建了2个订单,因此2月份的订单数量为2个。 4,6月之后的每个月对该特定订单的计数为1。

WAREHOUSENO ORDERNO ORDER DATE  CLOSED DATE
1           ABC     2/22/17      3/10/17
2           DEF     2/23/17      4/1/17
1           GHI     3/1/17       3/28/17
3           JKL     6/1/17  
2           MNO     9/1/17       10/12/17
3           PQR     10/22/17     2/23/18
1           STU     12/5/17      12/28/17
2           VWX     2/8/18  
3           YZ      3/15/18

最后,我们想总结每个月的所有计数,按仓库和年。

     Month                                          
     WAREHOUSE    Jan   Feb   Mar  Apr  May Jun Jul Aug Sep Oct Nov Dec
         1          0    1     1     0   0    0  0   0   0   0   0   1
2017     2          0    1     1     0   0    0  0   0   1   1   0   0
         3          0    0     0     0   0    1  1   1   1   2   2   2
TOTAL OPEN               2     2              1  1   1   2   3   2   3

         1          0     0    0     0                          
2018     2          1     1    1     1    
         3          1     1    2     2    
TOTAL OPEN          2     1    3     3

非常感谢这方面的一些方向!

2 个答案:

答案 0 :(得分:0)

您是否每个月都在计算每个仓库的未结订单?如果是这样,我相信下面的代码会做你想要的:

declare @sampleData table
(
    warehouseNo int not null
    ,orderNo nvarchar(5) not null
    , orderDate DateTime not null
    , closedDate DateTime
)

insert @sampleData (warehouseNo, orderNo, orderDate, closedDate)
values (1 ,'ABC', '2017-02-22', '2017-03-10')
,      (2 ,'DEF', '2017-02-23', '2017-04-01')
,      (1 ,'GHI', '2017-03-01', '2017-03-28')
,      (3 ,'JKL', '2017-06-01', null)
,      (2 ,'MNO', '2017-09-01', '2017-10-12')
,      (3 ,'PQR', '2017-10-22', '2018-02-23')
,      (1 ,'STU', '2017-12-05', '2017-12-28')
,      (2 ,'VWX', '2018-02-08', null)  
,      (3 ,'YZ',  '2018-03-15', null)

declare @start datetime 
, @end datetime

select @start = dateadd(day,1-day(min(orderDate)),min(orderDate))
, @end = max(coalesce(closedDate, getutcdate()))
from @sampleData

;with allDates as 
(
    select @start FirstOfMonth

    union all

    select dateadd(month,1,FirstOfMonth) 
    from allDates
    where FirstOfMonth <= @end
)
, normalisedDates as --round all dates down to first of the month since we only care about month and year; not day
(
    select warehouseNo
    , dateadd(day,1 - datepart(day, orderDate), orderDate) orderDate
    , dateadd(day,1 - datepart(day, coalesce(closedDate, getutcdate())), coalesce(closedDate, getutcdate())) closedDate
    from @sampleData
)
select ad.FirstOfMonth
, nd.warehouseNo 
, count(nd.warehouseNo) OpenOrderCount
from allDates ad
left outer join normalisedDates nd
on ad.FirstOfMonth between nd.orderDate and nd.closedDate
group by ad.FirstOfMonth, nd.warehouseNo
order by ad.FirstOfMonth, nd.warehouseNo

SQL Fiddle Example

更新

关于按月进行轮播的问题;肯定的。

请点击此处查看有关透视的精彩文章:https://blog.sqlauthority.com/2008/06/07/sql-server-pivot-and-unpivot-table-examples/

请参阅下文,了解您的方案的代码:

declare @start datetime 
, @end datetime

select @start = dateadd(day,1-day(min(orderDate)),min(orderDate))
, @end = max(coalesce(closedDate, getutcdate()))
from @sampleData

;with allDates as 
(
    select @start FirstOfMonth

    union all

    select dateadd(month,1,FirstOfMonth) 
    from allDates
    where FirstOfMonth <= @end
)
, normalisedDates as --round all dates down to first of the month since we only care about month and year; not day
(
    select warehouseNo
    , dateadd(day,1 - datepart(day, orderDate), orderDate) orderDate
    , dateadd(day,1 - datepart(day, coalesce(closedDate, getutcdate())), coalesce(closedDate, getutcdate())) closedDate
    from @sampleData
)
select warehouseNo, [1] Jan, [2] Feb, [3] Mar, [4] Apr, [5] May, [6] Jun, [7] Jul, [8] Aug, [9] Sep, [10] Oct, [11] Nov, [12] Dec
from 
(
    select datepart(month,ad.FirstOfMonth) MonthX
    , nd.warehouseNo 
    , count(nd.warehouseNo) OpenOrderCount
    from allDates ad
    left outer join normalisedDates nd
    on ad.FirstOfMonth between nd.orderDate and nd.closedDate
    group by ad.FirstOfMonth, nd.warehouseNo
) x
pivot 
(
    sum(OpenOrderCount) for MonthX in ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12]) 
) p
order by warehouseNo

答案 1 :(得分:0)

create table sampleData
(
    warehouseNo int not null
    ,orderNo nvarchar(5) not null
    , orderDate DateTime not null
    , closedDate DateTime
)

insert sampleData (warehouseNo, orderNo, orderDate, closedDate)
values (1 ,'ABC', '2017-02-22', '2017-03-10')
,      (2 ,'DEF', '2017-02-23', '2017-04-01')
,      (1 ,'GHI', '2017-03-01', '2017-03-28')
,      (3 ,'JKL', '2017-06-01', null)
,      (2 ,'MNO', '2017-09-01', '2017-10-12')
,      (3 ,'PQR', '2017-10-22', '2018-02-23')
,      (1 ,'STU', '2017-12-05', '2017-12-28')
,      (2 ,'VWX', '2018-02-08', null)  
,      (3 ,'YZ',  '2018-03-15', null)



SELECT ISNULL(CONVERT(CHAR(5), year(orderDate)), 'Total') AS [YEAR]
        ,ISNULL(warehouseNo, '') AS [Warehouse]
        ,count(CASE WHEN MONTH(orderDate) = 1 THEN orderNo END) AS JAN
        ,count(CASE WHEN MONTH(orderDate) = 2 THEN orderNo END) AS FEB
        ,count(CASE WHEN MONTH(orderDate) = 3 THEN orderNo END) AS MAR
        ,count(CASE WHEN MONTH(orderDate) = 4 THEN orderNo END) AS APR
        ,count(CASE WHEN MONTH(orderDate) = 5 THEN orderNo END) AS MAY
        ,count(CASE WHEN MONTH(orderDate) = 6 THEN orderNo END) AS JUN
        ,count(CASE WHEN MONTH(orderDate) = 7 THEN orderNo END) AS JUL
        ,count(CASE WHEN MONTH(orderDate) = 8 THEN orderNo END) AS AUG
        ,count(CASE WHEN MONTH(orderDate) = 9 THEN orderNo END) AS SEP
        ,count(CASE WHEN MONTH(orderDate) = 10 THEN orderNo END) AS OCT
        ,count(CASE WHEN MONTH(orderDate) = 11 THEN orderNo END) AS NOV
        ,count(CASE WHEN MONTH(orderDate) = 12 THEN orderNo END) AS DEC
    FROM sampleData
    GROUP BY ROLLUP(year(orderDate), warehouseNo)
        --order by ISNULL(CONVERT(char(5),year(orderDate)),'Total')