sql >> Database >  >> RDS >> Sqlserver

Groepeer op kolom en meerdere rijen in één rij meerdere kolommen

Zoals ik in de opmerkingen vermeld, heb je hier een PIVOT nodig of Kruistab; Ik geef de voorkeur aan het laatste, dus wat ik ga gebruiken.

De niet-dynamische oplossing hiervoor zou als volgt zijn:

WITH RNs AS(
    SELECT WorkOrder,
           TestType,
           Result,
           ROW_NUMBER() OVER (PARTITION BY WorkOrder, TestType ORDER BY (SELECT NULL)) AS RN --ORDER BY should be your ID/always ascending column
    FROM dbo.Result)
SELECT WorkOrder,
       TestType,
       MAX(CASE RN WHEN 1 THEN Result END) AS Result1,
       MAX(CASE RN WHEN 2 THEN Result END) AS Result2,
       MAX(CASE RN WHEN 3 THEN Result END) AS Result3
FROM RNs R
GROUP BY WorkOrder,
         TestType;

Het probleem is echter dat dit je "vastzet" in 3 resultaten, maar je suggereert dat er een onbepaald aantal resultaten is. Daarom heb je een dynamische oplossing nodig.

Het onderstaande werkt tot 100 resultaten. als je nodig meer kolommen dan dan, voeg dan meer toe CROSS JOIN s tot N in de CTE Tally . Dit resultaat ziet er ongeveer zo uit (wat nogal rommelig is).

DECLARE @SQL nvarchar(MAX),
        @CRLF nchar(2) = NCHAR(13) + NCHAR(10),
        @MaxTally int;

SELECT @MaxTally = MAX(C)
FROM (SELECT COUNT(*) AS C
      FROM dbo.Result
      GROUP BY WorkOrder,
               TestType) R;

WITH N AS(
    SELECT N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
    SELECT TOP (@MaxTally) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
    FROM N N1, N N2) --100 rows, add more Ns for more rows
SELECT @SQL = N'WITH RNs AS(' + @CRLF +
              N'    SELECT WorkOrder,' + @CRLF +
              N'           TestType,' + @CRLF +
              N'           Result,' + @CRLF +
              N'           ROW_NUMBER() OVER (PARTITION BY WorkOrder, TestType ORDER BY (SELECT NULL)) AS RN --ORDER BY should be your ID/always ascending column' + @CRLF +
              N'    FROM dbo.Result)' + @CRLF +
              N'SELECT WorkOrder,' + @CRLF +
              N'       TestType,' + @CRLF +
              --Using FOR XML PATH due to not knowing SQL Server version
              STUFF((SELECT N',' + @CRLF +
                            CONCAT(N'       MAX(CASE RN WHEN ',T.I,N' THEN Result END) AS Result',T.I)
                     FROM Tally T
                     ORDER BY T.I ASC
                     FOR XML PATH(N''),TYPE).value('(./text())[1]','nvarchar(MAX)'),1,3,N'') + @CRLF +
              N'FROM RNs R' + @CRLF +
              N'GROUP BY WorkOrder,' + @CRLF +
              N'         TestType;';

PRINT @SQL; --Your best friend.

EXEC sys.sp_executesql @SQL;


  1. Mysql-query om rijen dynamisch naar kolommen te converteren op basis van twee kolommen

  2. Hoofdletterongevoelig zoeken in Oracle

  3. Hoe te verwijzen naar JSON-sleutels die speciale tekens bevatten bij gebruik van OPENJSON, JSON_QUERY en JSON_VALUE (SQL Server)

  4. Spotlight Cloud gebruiken om blokkering van SQL Server op te lossen