SQL Server:选择每组行为一行

时间:2016-02-04 00:47:32

标签: sql-server-2008

很难描述我想知道的内容。粗略地说,它将每组行选择成一行“#34;

请参阅链接图片。

谢谢!

click here for an image: SQL Server, select each group of rows into a sing row

dbo.SourceTable

group   column1 column2
------------------------
A   A1  AA1
A   A2  AA2
A   A3  AA3
A   A4  AA4
A   A5  AA5
B   B1  BB1
B   B2  BB2
B   B3  BB3
B   B4  BB4
B   B5  BB5
C   C1  CC1
C   C2  CC2
C   C3  CC3
C   C4  CC4
C   C5  CC5
D   D1  DD1
D   D2  DD2
D   D3  DD3
D   D4  DD4
D   D5  DD5

期望的结果:

group   result1 result2 result3 result4 result5 result6 result7 result8 result9 result10
A   A1  AA1 A2  AA2 A3  AA3 A4  AA4 A5  AA5
B   B1  BB1 B2  BB2 B3  BB3 B4  BB4 B5  BB5
C   C1  CC1 C2  CC2 C3  CC3 C4  CC4 C5  CC5
D   D1  DD1 D2  DD2 D3  DD3 D4  DD4 D5  DD5

2 个答案:

答案 0 :(得分:2)

没有简单的方法来转动多个列。但有一个诀窍:

您可以连接两个列并对连接值执行操作。甚至更好:您可以让连接的值看起来像XML(而不将其转换为真正的XML )并对此进行调整。这种方法可以轻松获得值 typesafe

但我必须承认:打字很多: - )

DECLARE @tbl TABLE(groupColumn VARCHAR(1),Column1 VARCHAR(2),Column2 VARCHAR(3));
INSERT INTO @tbl VALUES
 ('A','A1','AA1')
,('A','A2','AA2')
,('A','A3','AA3')
,('A','A4','AA4')
,('A','A5','AA5')
,('B','B1','BB1')
,('B','B2','BB2')
,('B','B3','BB3')
,('B','B4','BB4')
,('B','B5','BB5')
,('C','C1','CC1')
,('C','C2','CC2')
,('C','C3','CC3')
,('C','C4','CC4')
,('C','C5','CC5')
,('D','D1','DD1')
,('D','D2','DD2')
,('D','D3','DD3')
,('D','D4','DD4')
,('D','D5','DD5');

SELECT p.groupColumn
      ,casted.Xml1.value('/x[1]','varchar(max)') AS Result1a
      ,casted.Xml1.value('/x[2]','varchar(max)') AS Result1b
      ,casted.Xml2.value('/x[1]','varchar(max)') AS Result2a
      ,casted.Xml2.value('/x[2]','varchar(max)') AS Result2b
      ,casted.Xml3.value('/x[1]','varchar(max)') AS Result3a
      ,casted.Xml3.value('/x[2]','varchar(max)') AS Result3b
      ,casted.Xml4.value('/x[1]','varchar(max)') AS Result4a
      ,casted.Xml4.value('/x[2]','varchar(max)') AS Result4b
      ,casted.Xml5.value('/x[1]','varchar(max)') AS Result5a
      ,casted.Xml5.value('/x[2]','varchar(max)') AS Result5b
      ,casted.Xml6.value('/x[1]','varchar(max)') AS Result6a
      ,casted.Xml6.value('/x[2]','varchar(max)') AS Result6b
      ,casted.Xml7.value('/x[1]','varchar(max)') AS Result7a
      ,casted.Xml7.value('/x[2]','varchar(max)') AS Result7b
      ,casted.Xml8.value('/x[1]','varchar(max)') AS Result8a
      ,casted.Xml8.value('/x[2]','varchar(max)') AS Result8b
      ,casted.Xml9.value('/x[1]','varchar(max)') AS Result9a
      ,casted.Xml9.value('/x[2]','varchar(max)') AS Result9b
      ,casted.Xml10.value('/x[1]','varchar(max)') AS Result10a
      ,casted.Xml10.value('/x[2]','varchar(max)') AS Result10b
FROM
(
    SELECT groupColumn
          ,'result' + CAST(ROW_NUMBER() OVER(PARTITION BY groupColumn ORDER BY Column1,Column2) AS VARCHAR(MAX)) AS ColumnName 
          ,'<x>' + Column1 + '</x><x>' + Column2 + '</x>' AS PivotColumn
    FROM @tbl
) AS pvt
PIVOT
(
    MIN(PivotColumn) FOR ColumnName IN(result1,result2,result3,result4,result5,result6,result7,result8,result9,result10)
) AS p
OUTER APPLY
(
    SELECT CAST(p.result1 AS XML) AS Xml1
          ,CAST(p.result2 AS XML) AS Xml2
          ,CAST(p.result3 AS XML) AS Xml3
          ,CAST(p.result4 AS XML) AS Xml4
          ,CAST(p.result5 AS XML) AS Xml5
          ,CAST(p.result6 AS XML) AS Xml6
          ,CAST(p.result7 AS XML) AS Xml7
          ,CAST(p.result8 AS XML) AS Xml8
          ,CAST(p.result9 AS XML) AS Xml9
          ,CAST(p.result10 AS XML) AS Xml10
) AS casted

结果

groupColumn Result1a    Result1b    Result2a    Result2b    Result3a    Result3b    Result4a    Result4b    Result5a    Result5b    Result6a    Result6b    Result7a    Result7b    Result8a    Result8b    Result9a    Result9b    Result10a   Result10b
A   A1  AA1 A2  AA2 A3  AA3 A4  AA4 A5  AA5 NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
B   B1  BB1 B2  BB2 B3  BB3 B4  BB4 B5  BB5 NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
C   C1  CC1 C2  CC2 C3  CC3 C4  CC4 C5  CC5 NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
D   D1  DD1 D2  DD2 D3  DD3 D4  DD4 D5  DD5 NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL

答案 1 :(得分:1)

这是这样做的一种方式:

CREATE TABLE #tt(id INT IDENTITY(1,1),[group] VARCHAR(16),[column1] VARCHAR(16),[column2] VARCHAR(16))
INSERT INTO #tt([group],[column1],[column2])VALUES
    ('A','A1','AA1'),
    ('A','A2','AA2'),
    ('A','A3','AA3'),
    ('A','A4','AA4'),
    ('A','A5','AA5'),
    ('B','B1','BB1'),
    ('B','B2','BB2'),
    ('B','B3','BB3'),
    ('B','B4','BB4'),
    ('B','B5','BB5'),
    ('C','C1','CC1'),
    ('C','C2','CC2'),
    ('C','C3','CC3'),
    ('C','C4','CC4'),
    ('C','C5','CC5'),
    ('D','D1','DD1'),
    ('D','D2','DD2'),
    ('D','D3','DD3'),
    ('D','D4','DD4'),
    ('D','D5','DD5');

;WITH group_order AS (
    SELECT
        *,
        group_order_id=ROW_NUMBER() OVER (PARTITION BY [group] ORDER BY id)
    FROM
        #tt
)
SELECT
    [group],
    result1=MAX(CASE WHEN group_order_id=1 THEN [column1] END),
    result2=MAX(CASE WHEN group_order_id=1 THEN [column2] END),
    result3=MAX(CASE WHEN group_order_id=2 THEN [column1] END),
    result4=MAX(CASE WHEN group_order_id=2 THEN [column2] END),
    result5=MAX(CASE WHEN group_order_id=3 THEN [column1] END),
    result6=MAX(CASE WHEN group_order_id=3 THEN [column2] END),
    result7=MAX(CASE WHEN group_order_id=4 THEN [column1] END),
    result8=MAX(CASE WHEN group_order_id=4 THEN [column2] END),
    result9=MAX(CASE WHEN group_order_id=5 THEN [column1] END),
    result10=MAX(CASE WHEN group_order_id=5 THEN [column2] END)
FROM
    group_order
GROUP BY
    [group];

DROP TABLE #tt;

结果:

+-------+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+
| group | result1 | result2 | result3 | result4 | result5 | result6 | result7 | result8 | result9 | result10 |
+-------+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+
| A     | A1      | AA1     | A2      | AA2     | A3      | AA3     | A4      | AA4     | A5      | AA5      |
| B     | B1      | BB1     | B2      | BB2     | B3      | BB3     | B4      | BB4     | B5      | BB5      |
| C     | C1      | CC1     | C2      | CC2     | C3      | CC3     | C4      | CC4     | C5      | CC5      |
| D     | D1      | DD1     | D2      | DD2     | D3      | DD3     | D4      | DD4     | D5      | DD5      |
+-------+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+