在 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;