如何解决在SQL中使用数据透视表的多行
我有一张桌子。
constraints
我使用数据透视。
Item | ID
--------------
1-A | 213
2-B | 432
3-C | 267
3-C | 879
3-C | 467
但是我只能得到一个值。
Select * from (
Select ID,Item
From data1
)R
Pivot (
Max(ID) For Item
in
([1-A],[2-B],[3-C])
)as pvt
如何获取3-C的所有值,希望得到这个结果。
1-A | 2-B | 3-C
-----------------
213 | 453 | 467
但是3-C,可能有一个或多个,我无法控制会出现多少个。
希望能帮助您回答,谢谢。
解决方法
这里的真正问题是行数不确定。这意味着您需要动态SQL,下一个问题是您没有可依赖的唯一值,因此我们也需要利用ROW_NUMBER
进行创新。这样就可以做到这一点,虽然不是很漂亮,但是可以“工作”。
CREATE TABLE dbo.YourTable (Item char(3),ID int);
INSERT INTO dbo.YourTable (Item,ID)
VALUES('1-A',213),('2-B',432),('3-C',267),879),467);
GO
DECLARE @SQL nvarchar(MAX),@CRLF nchar(2) = NCHAR(13) + NCHAR(10);
DECLARE @Delimiter nvarchar(30) = N',' + @CRLF + N' ';
WITH RNs AS(
SELECT Item,ID,ROW_NUMBER() OVER (ORDER BY Item) AS RN
FROM dbo.YourTable)
SELECT @SQL = N'WITH RNs AS(' + @CRLF +
N' SELECT Item,' + @CRLF +
N' ID,' + @CRLF +
N' ROW_NUMBER() OVER (ORDER BY Item) AS RN' + @CRLF +
N' FROM dbo.YourTable)' + @CRLF +
N'SELECT ' +
STRING_AGG(CONCAT(N'MAX(CASE WHEN Item = ',QUOTENAME(R.Item,''''),N' AND RN = ',R.RN,N' THEN R.ID END) AS ',QUOTENAME(R.Item)),@Delimiter) WITHIN GROUP (ORDER BY R.Item,R.RN) + @CRLF +
N'FROM RNs R;'
FROM RNs R;
PRINT @SQL;
EXEC sys.sp_executesql @SQL;
GO
DROP TABLE dbo.YourTable;
我假设您正在使用SQL Server的最新版本。如果没有,则需要用较旧的STRING_AGG
方法替换FOR XML PATH
。
由于列数未知,您将需要使用Dynamic SQL
。查询是动态表单,并使用sp_executesql
执行查询
看起来您想要一个Item
和ID
组合的独特价值,所以我在这里使用GROUP BY Item,ID
。
declare @sql nvarchar(max)
SELECT @sql = isnull(@sql + ',','SELECT ')
+ CONVERT(VARCHAR(10),ID) + ' AS ' + QUOTENAME(Item)
FROM data1
GROUP BY Item,ID
ORDER BY Item,ID
-- PRINT @sql
exec sp_executesql @sql
示例:dbfiddle
,另一种方法是使用3-C
将结果放在string_agg()
值的单个列中:
select string_agg(case when item = '[1-A]' then id end,') within group (order by id) as id_1_a,string_agg(case when item = '[2-B]' then id end,') within group (order by id) as id_2_b,string_agg(case when item = '[3-C]' then id end,') within group (order by id) as id_3_c
from data1;
这不是您指定的确切结果集,但它可能会满足您的需要。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。