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。
列:
- 日期 - 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
是否指定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;
我有 Table1,我需要一个查询来填充 Table2:
此处的问题与日期列有关。我想知道每天location/partner组合的过程。这里的主要问题是我无法选择 DateCreated 并将其设为默认日期,因为它不一定涵盖整个日期范围,就像本例中没有 2015-01-07 和 2015-01-09 一样。与其他日期相同的情况。
所以,我的想法是首先 select 日期来自一些包含所需日期范围的 table,然后对来自 cte 的每一天/location/partner 组合执行计算,但在那种情况下我不知道如何连接 LocationId 和 PartnerId。
列:
- 日期 - 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
是否指定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;