按周数分组,包括空周和对其他列求和
Group by week number including empty weeks and sum other column
我正在尝试从 SQL 服务器中的 table select,以便它将我的 FinalDate
列分组为周数并对 ThisApp
下一个单元格中那一周的列。我上网查了一下,似乎找不到我要找的东西。
我想知道这是否是我可以在 T-SQL 中做的事情?
目前这些是我 table 中的行:
FinalDate ThisApp
------------------------
15/04/2016 20459.92
29/05/2016 7521.89
30/05/2016 5963.61
31/05/2016 3293.72
03/06/2016 27413.20
04/06/2016 8392.16
05/06/2016 7789.46
05/06/2016 11414.73
10/06/2016 48893.46
11/06/2016 14685.47
11/06/2016 7030.03
我想用周数替换 FinalDate
列并对每个周数求和 This App
。
另外::
我需要它来显示连续的周数,所以我不希望它跳过任何周,例如:
FinalDate ThisApp
------------------------
01/01/2016 10.00 -- (Would be week 1)
02/01/2016 10.00 -- (Would be week 1)
15/01/2016 10.00 -- (Would be week 3)
会显示为:
FinalDate ThisApp
------------------------
1 20.00
2 0.00 --This would show as 0.00 because there was no week 2.
3 10.00
我理解这是一个非常具体的要求,这就是为什么我想知道我是否可以在 SQL 中做到这一点。
SELECT DATEPART(WEEK, FinalDate) FinalDate
, SUM(ThisApp) ThisApp
FROM Your_Table
GROUP BY DATEPART(WEEK, FinalDate)
为了获得数据集中不存在的周数 0
,您必须创建一个 table,其中包含周数 (1-52) 和 right join
。在那种情况下,你会得到类似的东西:
SELECT wk.Number
, ISNULL(SUM(ThisApp), 0)
FROM Your_Table T
RIGHT JOIN WeekNumbers wk
ON wk.Number = DATEPART(WEEK, T.FinalDate)
GROUP BY wk.Number
DECLARE @tmp table(dat datetime,
val float)
insert into @tmp
values ('15/04/2016' , 20459.92),
('29/05/2016', 7521.89),
('30/05/2016', 5963.61),
('31/05/2016', 3293.72),
('03/06/2016', 27413.20),
('04/06/2016', 8392.16),
('05/06/2016', 7789.46),
('05/06/2016', 11414.73),
('10/06/2016', 48893.46),
('11/06/2016', 14685.47),
('11/06/2016', 7030.03)
SELECT Weeknumb,
ISNULL(sumvals,0) as weekval
FROM
(SELECT DATEPART(ISOWK,DATEADD(wk,t2.number,'2016')) as Weeknumb
FROM master..spt_values t2
WHERE t2.type = 'P'
AND t2.number <= 255
AND YEAR(DATEADD(wk,t2.number,'2016'))=2016)allWeeks
LEFT JOIN
(SELECT sum(val) as sumvals,
datepart(ISOWK,dat) as weeks
FROM @tmp
GROUP BY datepart(ISOWK,dat) ) actualData
ON weeks = Weeknumb
ORDER BY Weeknumb asc
好了。 2016 年所有周的价值总和
HoneyBadger 的回答很好,但它将每年的第 1 周值分组在一起(因此 1975 年 1 月 1 日将与 2016 年 1 月 1 日分组)。为避免这种情况,您需要将年份添加到分组中。
此外,正如他指出的那样,如果您还希望返回 NULL 周数,则需要一个单独的 table。然而,你应该制作一个日历 table(Google 这个 - 它们很简单并且被广泛使用)并且你不应该只制作一个包含第 1-52 周的 table。
最后,为确保您不会为数据之前或之后的所有 Year/Weeks 返回 0 的记录,您需要添加开始日期和结束日期参数。您可以接受它们或将它们设置为 Your_Table.
中的第一个和最后一个 FinalDate
这是你应该使用的:
DECLARE @StartDate date = (SELECT MIN(FinalDate) FROM Your_Table),
@EndDate date = (SELECT MAX(FinalDate) FROM Your_Table)
SELECT YEAR(C.BaseDate) AS [Year],
DATEPART(WEEK, C.BaseDate) AS [Week],
ISNULL(SUM(YT.ThisApp), 0) AS [This App Total]
FROM Calendar C
LEFT OUTER JOIN Your_Table YT
ON C.BaseDate = CAST(YT.FinalDate AS DATE)
WHERE C.BaseDate BETWEEN @StartDate AND @EndDate
GROUP BY YEAR(C.BaseDate),
DATEPART(WEEK, C.BaseDate)
我正在尝试从 SQL 服务器中的 table select,以便它将我的 FinalDate
列分组为周数并对 ThisApp
下一个单元格中那一周的列。我上网查了一下,似乎找不到我要找的东西。
我想知道这是否是我可以在 T-SQL 中做的事情?
目前这些是我 table 中的行:
FinalDate ThisApp
------------------------
15/04/2016 20459.92
29/05/2016 7521.89
30/05/2016 5963.61
31/05/2016 3293.72
03/06/2016 27413.20
04/06/2016 8392.16
05/06/2016 7789.46
05/06/2016 11414.73
10/06/2016 48893.46
11/06/2016 14685.47
11/06/2016 7030.03
我想用周数替换 FinalDate
列并对每个周数求和 This App
。
另外::
我需要它来显示连续的周数,所以我不希望它跳过任何周,例如:
FinalDate ThisApp
------------------------
01/01/2016 10.00 -- (Would be week 1)
02/01/2016 10.00 -- (Would be week 1)
15/01/2016 10.00 -- (Would be week 3)
会显示为:
FinalDate ThisApp
------------------------
1 20.00
2 0.00 --This would show as 0.00 because there was no week 2.
3 10.00
我理解这是一个非常具体的要求,这就是为什么我想知道我是否可以在 SQL 中做到这一点。
SELECT DATEPART(WEEK, FinalDate) FinalDate
, SUM(ThisApp) ThisApp
FROM Your_Table
GROUP BY DATEPART(WEEK, FinalDate)
为了获得数据集中不存在的周数 0
,您必须创建一个 table,其中包含周数 (1-52) 和 right join
。在那种情况下,你会得到类似的东西:
SELECT wk.Number
, ISNULL(SUM(ThisApp), 0)
FROM Your_Table T
RIGHT JOIN WeekNumbers wk
ON wk.Number = DATEPART(WEEK, T.FinalDate)
GROUP BY wk.Number
DECLARE @tmp table(dat datetime,
val float)
insert into @tmp
values ('15/04/2016' , 20459.92),
('29/05/2016', 7521.89),
('30/05/2016', 5963.61),
('31/05/2016', 3293.72),
('03/06/2016', 27413.20),
('04/06/2016', 8392.16),
('05/06/2016', 7789.46),
('05/06/2016', 11414.73),
('10/06/2016', 48893.46),
('11/06/2016', 14685.47),
('11/06/2016', 7030.03)
SELECT Weeknumb,
ISNULL(sumvals,0) as weekval
FROM
(SELECT DATEPART(ISOWK,DATEADD(wk,t2.number,'2016')) as Weeknumb
FROM master..spt_values t2
WHERE t2.type = 'P'
AND t2.number <= 255
AND YEAR(DATEADD(wk,t2.number,'2016'))=2016)allWeeks
LEFT JOIN
(SELECT sum(val) as sumvals,
datepart(ISOWK,dat) as weeks
FROM @tmp
GROUP BY datepart(ISOWK,dat) ) actualData
ON weeks = Weeknumb
ORDER BY Weeknumb asc
好了。 2016 年所有周的价值总和
HoneyBadger 的回答很好,但它将每年的第 1 周值分组在一起(因此 1975 年 1 月 1 日将与 2016 年 1 月 1 日分组)。为避免这种情况,您需要将年份添加到分组中。
此外,正如他指出的那样,如果您还希望返回 NULL 周数,则需要一个单独的 table。然而,你应该制作一个日历 table(Google 这个 - 它们很简单并且被广泛使用)并且你不应该只制作一个包含第 1-52 周的 table。
最后,为确保您不会为数据之前或之后的所有 Year/Weeks 返回 0 的记录,您需要添加开始日期和结束日期参数。您可以接受它们或将它们设置为 Your_Table.
中的第一个和最后一个 FinalDate这是你应该使用的:
DECLARE @StartDate date = (SELECT MIN(FinalDate) FROM Your_Table),
@EndDate date = (SELECT MAX(FinalDate) FROM Your_Table)
SELECT YEAR(C.BaseDate) AS [Year],
DATEPART(WEEK, C.BaseDate) AS [Week],
ISNULL(SUM(YT.ThisApp), 0) AS [This App Total]
FROM Calendar C
LEFT OUTER JOIN Your_Table YT
ON C.BaseDate = CAST(YT.FinalDate AS DATE)
WHERE C.BaseDate BETWEEN @StartDate AND @EndDate
GROUP BY YEAR(C.BaseDate),
DATEPART(WEEK, C.BaseDate)