sql join和按生成的日期范围分组

时间:2015-03-05 14:25:24

标签: sql join common-table-expression date-range

我有Table1,我需要一个查询来填充Table2:

enter image description here

问题在于Date列。我想知道每天的位置/合作伙伴组合的过程。这里的主要问题是我无法选择DateCreated并将其作为默认日期,因为它不一定涵盖整个日期范围,例如在此示例中它没有2015-01-07和2015年1月9日。与其他日期相同的情况。

所以,我的想法是首先从包含所需日期范围的某个表中选择日期,然后从cte执行每天/位置/合作伙伴组合的计算,但在这种情况下,我无法弄清楚如何制作加入LocationId和PartnerId。

列:

  • Date - CreatedItems - Table1.DateCreated = Table2.Date
  • 创建的项目数
  • DeliveredItems - Table1.DateDateOut = Table2.Date
  • 的交付项目数
  • CycleTime - 已交付项目的天数位于该位置(DateOut - DateIn + 1)

我从这样的事情开始,但它非常像我完全错过了它的观点:

with d as
(
    select date from DimDate
    where date between DATEADD(DAY, -365, getdate()) and getdate()
),

cr as -- created items
(
    select 
    DateCreated, 
    LocationId,
    PartnerId,
    CreatedItems = count(*)
    from Table1
    where DateCreated is not null
    group by DateCreated, 
    LocationId,
    PartnerId
),

del as -- delivered items
(
    select 
    DateOut, 
    LocationId,
    ParnerId,
    DeliveredItems = count(*),
    CycleTime = DATEDIFF(Day, DateOut, DateIn)
    from Table1
    where DateOut is not null
    and Datein is not null
    group by DateOut, 
    LocationId,
    PartnerId
)

select
d.Date
from d
LEFT OUTER JOIN cr on cr.DateCreated = d.Date -- MISSING JOIN PER LocationId and PartnerId
LEFT OUTER JOIN del on del.DateCompleted = d.Date -- MISSING JOIN PER LocationId and PartnerId

2 个答案:

答案 0 :(得分:1)

with range(days) as (
    select 0 union all select 1 union all select 2 union all
    select 3 union all select 4 union all select 5 union all
    select 6 /* extend as necessary */
)
select dateadd(day, r.days, t.DateCreated) as "Date", locationId, PartnerId,
    sum(
        case
            when dateadd(day, r.days, t.DateCreated) = t.DateCreated
            then 1 else 0
        end) as CreatedItems,
    sum(
        case
            when dateadd(day, r.days, t.DateCreated) = t.Dateout
            then 1 else 0
        end) as DeliveredItems,
    sum(
        case
            when dateadd(day, r.days, t.DateCreated) = t.Dateout
            then datediff(days, t.DateIn, t.DateOut) + 1 else 0
        end) as CycleTime
from
    <yourtable> as t
    inner join range as r
        on r.days between 0 and datediff(day, t.DateCreated, t.DateOut)
group by dateadd(day, r.days, t.DateCreated), LocationId, PartnerId;

如果您只想要结束日期(而不是之间的所有日期),这可能是更好的方法:

with range(dt) as (
    select distinct DateCreated from T union
    select distinct DateOut from T
)
select r.dt as "Date", locationId, PartnerId,
    sum(
        case
            when r.dt = t.DateCreated
            then 1 else 0
        end) as CreatedItems,
    sum(
        case
            when r.dt = t.Dateout
            then 1 else 0
        end) as DeliveredItems,
    sum(
        case
            when r.dt = t.Dateout
            then datediff(days, t.DateIn, t.DateOut) + 1 else 0
        end) as CycleTime
from
    <yourtable> as t
    inner join range as r
        on r.dt in (t.DateCreated, t.DateOut)
group by r.dt, LocationId, PartnerId;

答案 1 :(得分:0)

如果要指定WHERE子句?像这样的东西:

WHERE cr.LocationId = del.LocationId AND
      cr.PartnerId = del.PartnerId