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

sql join and group by generated date range

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

此处的问题与日期列有关。我想知道每天location/partner组合的过程。这里的主要问题是我无法选择 DateCreated 并将其设为默认日期,因为它不一定涵盖整个日期范围,就像本例中没有 2015-01-07 和 2015-01-09 一样。与其他日期相同的情况。

所以,我的想法是首先 select 日期来自一些包含所需日期范围的 table,然后对来自 cte 的每一天/location/partner 组合执行计算,但在那种情况下我不知道如何连接 LocationId 和 PartnerId。

列:

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

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

是否指定WHERE子句?类似的东西:

WHERE cr.LocationId = del.LocationId AND
      cr.PartnerId = del.PartnerId
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;