在 DATENAME 函数上使用 group by 的东西
Stuff with group by on DATENAME function
情况:
假设有一个 table ALPHA
,其中包含一列 ALPHA.ID_BETA
(Table BETA
上的外键)和一列 ALPHA.CREATIONDATE (DATETIME NOT NULL)
.
现在假设 Table ALPHA
中有以下记录:
ID
CREATIONDATE (YYYY-MM-DD)
ID_BETA
1
2022-05-26 00:00:00.000
1
2
2022-02-02 00:00:00.000
1
3
2022-01-28 00:00:00.000
1
4
2022-01-02 00:00:00.000
1
现在想象 Table BETA
看起来像这样(为简单起见,我省略了其他列:
ID
1
期望的输出:
是一个连接 CREATIONDATE
的所有值(格式:DATENAME + YYYY)的值,用于单个 ID_BETA
按日期升序排列。在此示例中,输出应为 January 2022, February 2022, May 2022
(显然取决于语言设置)
我尝试过的:
SELECT STUFF(
(SELECT ', '
+ DATENAME(MONTH,(ALPHA.CREATIONDATE)) + DATENAME(YEAR, ALPHA.CREATIONDATE)
FROM ALPHA
WHERE ALPHA.ID_BETA = 1
GROUP BY ALPHA.CREATIONDATE
ORDER BY ALPHA.CREATIONDATE ASC
FOR XML PATH('')),1, 1, '')
然而,这不会给我不同的值。尝试明显的 DISTINCT
语句会给我以下错误:
Server: Msg 145, Level 15, State 1, Line 1 ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
请注意,我无法使用“新”STRING_AGG 函数解决此问题,因为它仅在 SQL-Server2017 向上支持。
如错误消息所述,完全按照 select 子句中的表达式排序
SELECT STUFF(
(SELECT distinct ', '
+ DATENAME(MONTH,(ALPHA.CREATIONDATE)) + DATENAME(YEAR, ALPHA.CREATIONDATE)
FROM ALPHA
WHERE ALPHA.ID_BETA = 1
GROUP BY ALPHA.CREATIONDATE
ORDER BY ', '
+ DATENAME(MONTH,(ALPHA.CREATIONDATE)) + DATENAME(YEAR, ALPHA.CREATIONDATE) ASC
FOR XML PATH('')),1, 1, '')
您需要按 EOMONTH(CREATIONDATE)
分组和排序,以便每月按一个日期分组,而不是仅按 CREATIONDATE
.
分组
Note also that you need .value
to unescape the XML, and the third parameter of STUFF
should be the same as the length of the separator
SELECT STUFF(
(SELECT
', ' + DATENAME(MONTH, EOMONTH(a.CREATIONDATE)) + DATENAME(YEAR, EOMONTH(a.CREATIONDATE))
FROM ALPHA a
WHERE a.ID_BETA = 1
GROUP BY
EOMONTH(a.CREATIONDATE)
ORDER BY
EOMONTH(a.CREATIONDATE)
FOR XML PATH(''), TYPE
).value('text()[1]','nvarchar(max)'), 1, LEN(', '), '')
如果您想对 BETA
的每一行执行此操作,您可以使用 CROSS APPLY
或子查询:
SELECT STUFF(
(SELECT
', ' + DATENAME(MONTH, EOMONTH(a.CREATIONDATE)) + DATENAME(YEAR, EOMONTH(a.CREATIONDATE))
FROM ALPHA a
WHERE a.ID_BETA = b.ID
GROUP BY
EOMONTH(a.CREATIONDATE)
ORDER BY
EOMONTH(a.CREATIONDATE)
FOR XML PATH(''), TYPE
).value('text()[1]','nvarchar(max)'), 1, LEN(', '), '')
FROM BETA b;
情况:
假设有一个 table ALPHA
,其中包含一列 ALPHA.ID_BETA
(Table BETA
上的外键)和一列 ALPHA.CREATIONDATE (DATETIME NOT NULL)
.
现在假设 Table ALPHA
中有以下记录:
ID | CREATIONDATE (YYYY-MM-DD) | ID_BETA |
---|---|---|
1 | 2022-05-26 00:00:00.000 | 1 |
2 | 2022-02-02 00:00:00.000 | 1 |
3 | 2022-01-28 00:00:00.000 | 1 |
4 | 2022-01-02 00:00:00.000 | 1 |
现在想象 Table BETA
看起来像这样(为简单起见,我省略了其他列:
ID |
---|
1 |
期望的输出:
是一个连接 CREATIONDATE
的所有值(格式:DATENAME + YYYY)的值,用于单个 ID_BETA
按日期升序排列。在此示例中,输出应为 January 2022, February 2022, May 2022
(显然取决于语言设置)
我尝试过的:
SELECT STUFF(
(SELECT ', '
+ DATENAME(MONTH,(ALPHA.CREATIONDATE)) + DATENAME(YEAR, ALPHA.CREATIONDATE)
FROM ALPHA
WHERE ALPHA.ID_BETA = 1
GROUP BY ALPHA.CREATIONDATE
ORDER BY ALPHA.CREATIONDATE ASC
FOR XML PATH('')),1, 1, '')
然而,这不会给我不同的值。尝试明显的 DISTINCT
语句会给我以下错误:
Server: Msg 145, Level 15, State 1, Line 1 ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
请注意,我无法使用“新”STRING_AGG 函数解决此问题,因为它仅在 SQL-Server2017 向上支持。
如错误消息所述,完全按照 select 子句中的表达式排序
SELECT STUFF(
(SELECT distinct ', '
+ DATENAME(MONTH,(ALPHA.CREATIONDATE)) + DATENAME(YEAR, ALPHA.CREATIONDATE)
FROM ALPHA
WHERE ALPHA.ID_BETA = 1
GROUP BY ALPHA.CREATIONDATE
ORDER BY ', '
+ DATENAME(MONTH,(ALPHA.CREATIONDATE)) + DATENAME(YEAR, ALPHA.CREATIONDATE) ASC
FOR XML PATH('')),1, 1, '')
您需要按 EOMONTH(CREATIONDATE)
分组和排序,以便每月按一个日期分组,而不是仅按 CREATIONDATE
.
Note also that you need
.value
to unescape the XML, and the third parameter ofSTUFF
should be the same as the length of the separator
SELECT STUFF(
(SELECT
', ' + DATENAME(MONTH, EOMONTH(a.CREATIONDATE)) + DATENAME(YEAR, EOMONTH(a.CREATIONDATE))
FROM ALPHA a
WHERE a.ID_BETA = 1
GROUP BY
EOMONTH(a.CREATIONDATE)
ORDER BY
EOMONTH(a.CREATIONDATE)
FOR XML PATH(''), TYPE
).value('text()[1]','nvarchar(max)'), 1, LEN(', '), '')
如果您想对 BETA
的每一行执行此操作,您可以使用 CROSS APPLY
或子查询:
SELECT STUFF(
(SELECT
', ' + DATENAME(MONTH, EOMONTH(a.CREATIONDATE)) + DATENAME(YEAR, EOMONTH(a.CREATIONDATE))
FROM ALPHA a
WHERE a.ID_BETA = b.ID
GROUP BY
EOMONTH(a.CREATIONDATE)
ORDER BY
EOMONTH(a.CREATIONDATE)
FOR XML PATH(''), TYPE
).value('text()[1]','nvarchar(max)'), 1, LEN(', '), '')
FROM BETA b;