sql >> データベース >  >> RDS >> Sqlserver

複数の行を 1 行に結合し、行数に応じて列を追加する

    オプションを dynamicSQL APPLY( ) および PIVOT オペレーター。このシナリオでは、列 Col4 でソートされた結果の列の順序です。

    DECLARE @cols nvarchar(max),
            @query nvarchar(max)
    SELECT @cols = 
      STUFF((SELECT x.ColName
             FROM (
                   SELECT ',' + QUOTENAME('Col' + CAST(3 + ROW_NUMBER() OVER(PARTITION BY Col1, Col2, Col3 ORDER BY Col4) AS nvarchar(10))) AS ColName,
                          ROW_NUMBER() OVER(PARTITION BY Col1, Col2, Col3 ORDER BY Col4) AS rn
                   FROM dbo.test31 CROSS APPLY (VALUES('Col'), ('Col'), ('Col')) o(Col)) x
             GROUP BY x.ColName, x.rn
             ORDER BY x.rn                   
             FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)'), 1, 1, '')
    SET @query = 
      'SELECT * FROM 
        (      
         SELECT t.Col1, t.Col2, t.Col3,            
                ''Col'' + CAST(3 + ROW_NUMBER() OVER(PARTITION BY t.Col1, t.Col2, t.Col3 ORDER BY t.Col4) AS nvarchar(10)) AS ColName,            
                COALESCE(CAST(o.oCol4 AS nvarchar(10)), o.oCol5, o.oCol6) AS ListValues            
         FROM dbo.test31 t CROSS APPLY (
                                        SELECT oCol4, oCol5, oCol6
                                        FROM (VALUES (t.Col4, NULL, NULL),
                                                     (NULL, t.Col5, NULL),
                                                     (NULL, NULL, t.Col6))
                                        x(oCol4, oCol5, oCol6)
                                        ) o
         ) x
         PIVOT
          (
           MAX(ListValues) FOR ColName IN(' + @cols + ')
           ) p'
    EXEC (@query)
    

    SQLFiddle のデモ

    「プラント、ブランド、エリア 1、ダウンタイム 1、理由 1、エリア 2、ダウンタイム 2、理由 2 など」のような列名のオプション。

    DECLARE @cols nvarchar(max),
            @query nvarchar(max)
    SELECT @cols = 
      STUFF((SELECT ',' + QUOTENAME(o.Col) AS ColName                
             FROM
              (
               SELECT *, CAST(ROW_NUMBER() OVER(PARTITION BY Plant, Brand ORDER BY Area) AS nvarchar(10)) AS rn
               FROM dbo.test35) t CROSS APPLY (VALUES('Area' + t.rn), ('DownTime' + t.rn), ('Reasons' + t.rn)
               ) o(Col)
             GROUP BY o.Col, t.rn
             ORDER BY t.rn                   
             FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)'), 1, 1, '')       
    
    SET @query = 
      'SELECT * FROM 
        (      
         SELECT t.Plant, t.Brand, o.ColName,            
                COALESCE(CAST(o.Area AS nvarchar(10)), o.DownTime, o.Reasons) AS ListValues
         FROM
          (
           SELECT Plant, Brand, Area, DownTime, Reasons,
                  CAST(ROW_NUMBER() OVER(PARTITION BY Plant, Brand ORDER BY Area) AS nvarchar(10)) AS rn            
           FROM dbo.test35) t CROSS APPLY (
                                          SELECT Area, DownTime, Reasons, ColName
                                          FROM (VALUES (t.Area, NULL, NULL, ''Area'' + t.rn),
                                                       (NULL, t.DownTime, NULL, ''DownTime'' + t.rn),
                                                       (NULL, NULL, t.Reasons, ''Reasons'' + t.rn))
                                          x(Area, DownTime, Reasons, ColName)
                                          ) o
          ) x
         PIVOT
          (
           MAX(ListValues) FOR ColName IN(' + @cols + ')
           ) p'
    EXEC (@query) 
    

    SQLFiddle のデモ




    1. ビットマップ画像とテキストを保存するためにSQLiteデータベースを実装する方法は?

    2. 接続が閉じられた後の操作は許可されませんMYSQL

    3. 現在の日付を日時形式のmySQLで挿入します

    4. OracleSQLDeveloperでtnsnames.oraを使用する