将行显示为列

时间:2012-05-10 02:24:29

标签: sql sql-server pivot coalesce

这是我的SQL表:

Table1
Col1   Col2
a      1
a      2
a      3
b      1
c      1
c      2

如何查询此表格以显示如下?

col1,value1,value2,value3
a,1,2,3
b,1,null,null
c,1,2,null

col1中的每个值永远不会超过5条记录。我不知道col2中的值是什么,它们将是动态的。

2 个答案:

答案 0 :(得分:3)

如果您使用的是SQL 2005或更高版本,PIVOT是一个不错的选择。 对于静态查询,您可以假设最大值为1,2,3 ......并使用PIVOT,如下所示:

SELECT Col1 AS 'Col1', 
[1], [2], [3], [4], [5]
FROM
(SELECT Col1, Col2 
    FROM dbo.Table1) AS SourceTable
PIVOT
(
MAX(Col2)
FOR Col2 IN ([1], [2], [3], [4], [5])
) AS PivotTable;

如果接受动态SQL,则可以构建SQL语句并使用sp_executesql执行它:

DECLARE @Values VARCHAR(1000)
DECLARE @SQL NVARCHAR(MAX)
SET @Values = NULL

SELECT 
    @Values = COALESCE(@Values + ', ', '') +  + '[' + CAST(Col2 AS VARCHAR) + ']'
FROM (SELECT DISTINCT TOP 100 PERCENT Col2 FROM dbo.Table1 ORDER BY 1) T

SET @SQL = '
SELECT Col1 AS ''Col1'', 
' + @Values + '
FROM
(SELECT Col1, Col2 
    FROM dbo.Table1) AS SourceTable
PIVOT
(
MAX(Col2)
FOR Col2 IN (' + @Values + ')
) AS PivotTable;
'
EXECUTE sp_executesql @SQL

答案 1 :(得分:0)

数据库并不擅长做你要求的事情。虽然我确信这是可能的,并且有人会在这里发布解决方案,但也许你可以用一点bash脚本让你的生活更轻松。

此代码获取第1列中所有唯一值的列表。然后,它会在表中查询第1列中第1列中给定值的所有值。“tr”命令用commmas替换换行符sed命令将最后一个逗号切换回换行符。

我感觉如果您发布了有关您的特定问题的更多信息,那么可能会有更好的解决方案来解决您的问题。任何纯查询的解决方案都会涉及将表连接到自身5次,这可能需要进行大量处理,具体取决于表的大小。

注意:由于问题没有详细说明,我做了几个假设。我假设我们使用postgresql并且数据库名为test。

#!/bin/bash                                                                     

echo "select distinct col1 from table1 order by col1" | psql -At test | while read col1;do
    echo -n "$col1,"
    echo "select col2 from table1 where col1='$col1' order by col2" | psql -At test | tr '\n' ',' | sed s/,$/\n/'

done

然后输出:

a,1,2,3
b,1
c,1,2