2017-10-08 1 views
2

Ich habe ein Ergebnis wie folgt festgelegt:Kategorien alle Termine für Monat in SQL Server mit Set-basierten Ansatz

--------------------------- 
|  AllDates   | 
--------------------------- 
| 2017-05-12 00:00:00.000 | 
| 2017-05-14 00:00:00.000 | 
| 2017-08-10 00:00:00.000 | 
| 2017-08-13 00:00:00.000 | 
| 2018-02-12 00:00:00.000 | 
| 2018-05-15 00:00:00.000 | 
| 2018-05-16 00:00:00.000 | 
--------------------------- 

Jetzt muss ich alle Termine in die folgende Zeichenfolge kategorisieren SQL Server mit

-------------------------------------------------- 
|     Result      | 
-------------------------------------------------- 
| May: 12, 14, Aug: 10, 13, Feb: 12, May: 15, 16 | 
-------------------------------------------------- 

Ohne Verwendung der benutzerdefinierten Funktion in SQL Server, kann dies nur mithilfe von Set-basierten Ansatz erreicht werden?

Antwort

1

Für SQL Server 2014 können Sie verwenden:

DECLARE @DataSource TABLE 
(
    [value] DATETIME2 
); 

INSERT INTO @DataSource ([value]) 
VALUES ('2017-05-12 00:00:00.000') 
     ,('2017-05-14 00:00:00.000') 
     ,('2017-08-10 00:00:00.000') 
     ,('2017-08-13 00:00:00.000') 
     ,('2018-02-12 00:00:00.000') 
     ,('2018-05-15 00:00:00.000') 
     ,('2018-05-16 00:00:00.000'); 

WITH DataSource AS 
(
    SELECT YEAR([value]) AS [Year] 
      ,MONTH([value]) AS [MonthID] 
      ,DATENAME(MONTH, [value]) AS [Month] 
      ,DAY([value]) AS [Day] 
    FROM @DataSource 
), 
DataSourceDays AS 
(
    SELECT DISTINCT [Year] 
        ,[MonthID] 
        ,[MONTH] + ':' + [value] AS [Days] 
    FROM DataSource T 
    CROSS APPLY 
    (
     SELECT STUFF 
     (
      (
       SELECT ',' + CAST([Day] AS VARCHAR(2)) 
       FROM DataSource S 
       WHERE T.[Year] = S.[Year] 
        AND T.[MonthID] = S.[MonthID] 
       ORDER BY [Day] 
       FOR XML PATH(''), TYPE 
      ).value('.', 'VARCHAR(MAX)') 
      ,1 
      ,1 
      ,'' 
     ) 
    ) DS([value]) 
) 
SELECT STUFF 
(
    (
     SELECT ', ' + CAST([Days] AS VARCHAR(12)) 
     FROM DataSourceDays 
     FOR XML PATH(''), TYPE 
    ).value('.', 'VARCHAR(MAX)') 
    ,1 
    ,2 
    ,'' 
); 

Im ersten CTE bekommen wir die Details, die wir verketten werden. In der zweiten verketten wir die Tage für jeden Monat und jedes Jahr. Im letzten Schritt verketten wir alle vorherigen Ergebnisse.


Und FYI, ist dies, wie die gleiche SQL Server 2017 Verwendung erfolgt:

WITH DataSource AS 
(
    SELECT YEAR ([value]) AS [Year] 
      ,MONTH([value]) AS [Month] 
      ,DATENAME(MONTH, [value]) + ':' + STRING_AGG(DAY([value]), ', ') WITHIN GROUP (ORDER BY [value]) AS [value] 
    FROM @DataSource 
    GROUP BY YEAR ([value]) 
      ,MONTH([value]) 
      ,DATENAME(MONTH, [value]) 
) 
SELECT STRING_AGG([value], ' ,') WITHIN GROUP (ORDER BY [Year], [Month]) 
FROM DataSource; 
Verwandte Themen