如何在一行中显示所有组合?

时间:2014-11-09 17:23:18

标签: sql-server tsql sql-server-2008-r2

我试图在这里找到类似的问题,但不能。这是我的问题的一个非常简化的版本。我有这张桌子 A

我有另一张桌子: B

我想显示这样的结果: enter image description here

此处的列数(在上一个结果集中)将根据每个ID的组合数而不同。这甚至可能吗?我对sql pivot的理解有限,但不确定这实际上是一个支点。欢迎任何想法。

1 个答案:

答案 0 :(得分:3)

使用Pivot是正确的,你可以将行转换为列。

CREATE TABLE #TableA
  (ID   INT,NAME VARCHAR(100))

INSERT INTO #TableA
VALUES     (1000,'Anna'),(2000,'Peter')

CREATE TABLE #TableB
  (ID    INT,City  VARCHAR(50),dates VARCHAR(50))

INSERT INTO #TableB
VALUES      (1000,'New york','2014-05-10' ),(1000,'Atlanta','2014-06-11'),
            (1000,'Los ang','2014-09-11'),(2000,'seattle','2014-02-10'),
            (2000,'miami','2014-03-11') 

SELECT id,
       Max([city1])  [City],
       Max([dates1]) [Dates],
       Max([city2])  [City],
       Max([dates2]) [Dates],
       Max([city3])  [City],
       Max([dates3]) [Dates]
FROM   (SELECT 'city'+ CONVERT(VARCHAR(50), Row_number() OVER(partition BY B.id ORDER BY dates)) cityrn,
               'dates'+ CONVERT(VARCHAR(50), Row_number() OVER(partition BY B.id ORDER BY dates)) datesrn,
               A.id,A.NAME,B.City,B.dates
        FROM   #TableB B
               JOIN #TableA a
                 ON A.id = B.ID) a 
               PIVOT (Max(City)
                    FOR cityrn IN([city1],[city2],[city3])) piv
               PIVOT (Max(dates)
                    FOR datesrn IN ([dates1],[dates2],[dates3])) piv1
        GROUP BY id

动态版本:

DECLARE @citycols  VARCHAR(max)='',
        @datsecols VARCHAR(max)='',
        @aggcitycols  VARCHAR(max)='',
        @aggdatsecols VARCHAR(max)=''
DECLARE @sql          NVARCHAR(max)

SELECT @citycols += ',[' + crn + ']'
FROM  (SELECT DISTINCT 'city'+ CONVERT(VARCHAR(50), Row_number() OVER(partition BY id ORDER BY dates)) crn
       FROM   #TableB) a

SELECT @datsecols += ',[' + drn + ']'
FROM   (SELECT DISTINCT 'dates'+ CONVERT(VARCHAR(50), Row_number() OVER(partition BY id ORDER BY dates)) drn
        FROM   #TableB) a

SELECT @citycols = RIGHT(@citycols, Len(@citycols) - 1)
SELECT @datsecols = RIGHT(@datsecols, Len(@datsecols) - 1)

SELECT @aggcitycols += ',' + crn
FROM  (SELECT DISTINCT 'max(city'+ CONVERT(VARCHAR(50), Row_number() OVER(partition BY id ORDER BY dates))+ ') City' crn
       FROM   #TableB) a

SELECT @aggdatsecols += ',' + drn
FROM   (SELECT DISTINCT 'max(dates'+ CONVERT(VARCHAR(50), Row_number() OVER(partition BY id ORDER BY dates))+ ') [Date]' drn
        FROM   #TableB) a

SELECT @aggcitycols = RIGHT(@aggcitycols, Len(@aggcitycols) - 1)
SELECT @aggdatsecols = RIGHT(@aggdatsecols, Len(@aggdatsecols) - 1) 



SET @sql='  SELECT id,' + @aggcitycols + ',' + @aggdatsecols+ '
                 FROM   (SELECT ''city''+ CONVERT(VARCHAR(50), Row_number() OVER(partition BY B.id ORDER BY dates)) cityrn,
                                ''dates''+ CONVERT(VARCHAR(50), Row_number() OVER(partition BY B.id ORDER BY dates)) datesrn
                                ,A.id,A.name,B.City,B.dates
                         FROM   #TableB b join #TableA a ON A.id = B.ID) a
                            PIVOT (Max(City)
                                 FOR cityrn IN(' + @citycols+ ')) piv
                            PIVOT (Max(dates)
                                 FOR datesrn IN (' + @datsecols+ ')) piv1
                         GROUP BY id
             '

EXEC Sp_executesql @sql 

输出

   +-----+--------+-----------+------------+---------+-----------+----------+-------------+
   | ID  |  NAME  | City      | Date       | City    |  Date     |  City    |   Date      |
   +-----+--------+-----------+------------+---------+-----------+----------+-------------+ 
   |1000 |  Anna  | New york  | 2014-05-10 | Atlanta | 2014-06-11|  Los ang |  2014-09-11 |
   +-----+--------+-----------+------------+---------+-----------+----------+-------------+ 
   |2000 |  Peter | seattle   | 2014-02-10 | miami   | 2014-03-11|  NULL    |   NULL      |
   +-----+--------+-----------+------------+---------+-----------+----------+-------------+