這演示瞭如何將問題分解成公用表表達式(CTE)中的步驟。請注意,您可以將最後的select
替換爲註釋select
之一以查看中間結果。這是測試,調試或理解正在發生的事情的便捷方式。
你所面對的問題之一就是試圖僅基於飲水日期總結數據。如果一棵樹在一個沒有澆水的月份裏種植,那麼它不會被計算在內。下面的代碼分別總結了日期範圍內的種植和供水情況,然後將它們組合成單個結果集。
-- Sample data.
declare @Trees as Table (TreeId Int Identity, CityId Int, DatePlanted Date);
declare @Waterings as Table (WateringId Int Identity, TreeId Int, DateWatered Date);
insert into @Trees (CityId, DatePlanted) values
(1, '20160115'), (1, '20160118'),
(1, '20160308'), (1, '20160318'), (1, '20160118'),
(1, '20170105'),
(1, '20170205'),
(1, '20170401'),
(2, '20160113'), (2, '20160130'),
(2, '20170226'), (2, '20170227'), (2, '20170228');
insert into @Waterings (TreeId, DateWatered) values
(1, '20160122'), (1, '20160129'), (1, '20160210'), (1, '20160601'),
(5, '20160120'), (5, '20160127'), (5, '20160215'), (5, '20160301'), (5, '20160515');
select * from @Trees;
select * from @Waterings;
-- Combine the data.
declare @StartDate as Date = '20100101', @EndDate as Date = '20200101';
with
-- Each tree with the year and month it was planted.
TreesPlanted as (
select CityId, TreeId,
DatePart(year, DatePlanted) as YearPlanted,
DatePart(month, DatePlanted) as MonthPlanted
from @Trees
where @StartDate <= DatePlanted and DatePlanted <= @EndDate),
-- Tree plantings summarized by city, year and month.
TreesPlantedSummary as (
select CityId, YearPlanted, MonthPlanted, Count(TreeId) as Trees
from TreesPlanted
group by CityId, YearPlanted, MonthPlanted),
-- Each watering and the year and month it occurred.
TreesWatered as (
select CityId, W.TreeId,
DatePart(year, W.DateWatered) as YearWatered,
DatePart(month, W.DateWatered) as MonthWatered
from @Trees as T left outer join
@Waterings as W on W.TreeId = T.TreeId
where @StartDate <= W.DateWatered and W.DateWatered <= @EndDate),
-- Waterings summarized by city, year and month.
TreesWateredSummary as (
select CityId, YearWatered, MonthWatered,
Count(distinct TreeId) as Trees, Count(TreeId) as Waterings
from TreesWatered
group by CityId, YearWatered, MonthWatered)
-- Combine the plantings and waterings for the specified period.
select Coalesce(TPS.CityId, TWS.CityId) as CityId,
Coalesce(TPS.YearPlanted, TWS.YearWatered) as Year,
Coalesce(TPS.MonthPlanted, TWS.MonthWatered) as Month,
Coalesce(TPS.Trees, 0) as TreesPlanted,
Coalesce(TWS.Trees, 0) as TreesWatered,
Coalesce(TWS.Waterings, 0) as Waterings
from TreesPlantedSummary as TPS full outer join
TreesWateredSummary as TWS on TWS.CityId = TPS.CityId and
TWS.YearWatered = TPS.YearPlanted and TWS.MonthWatered = TPS.MonthPlanted
order by CityId, Year, Month;
-- Alternative queries for testing/debugging/understanding:
-- select * from TreesPlantedSummary order by CityId, YearPlanted, MonthPlanted;
-- select * from TreesWateredSummary order by CityId, YearWatered, MonthWatered;
現在你想要在結果中包含缺失的月份(沒有活動),呃?
你有超過12個月的數據嗎?有時幾個月會重演 – HABO
'Group by t.CityId,Datepart(month,w.DateWatered),Datepart(year,w.DateWatered)''而不是'DATENAME(month,w.DateWatered)' – TriV
@habo - 是的,有很多年數據。這是爲什麼它是複製的,因爲幾個月?我如何解決它? – BattlFrog