如何旋转未知数量的列 &SQL Server 中没有聚合?
我有查询返回客户贷款的相关抵押品名称如下(1)但我只想像其他示例 (2) 那样连续只有一个不同的贷款编号和抵押品名称.一直在玩旋转但无法弄清楚,因为我没有汇总列,而且我不知道我将获得多少贷款数量,也不知道每笔贷款可能有多少抵押品.怎么做???在 SQL Server 2012 中可能吗?
I have query which returns clients loans with associated collateral names like below (1) but I want to have only one distinct loan number in a row and collateral names aside like on other example (2). Been playing with pivoting but cannot figure it out because I don't have aggregate column and I don't know how many loan numbers I will get neither how many collateral each loan may have. How to do that??? Possible in SQL Server 2012?
谢谢
(1)
loanid|name |Address |
1 |John |New York|
1 |Carl |New York|
1 |Henry |Boston |
2 |Robert|Chicago |
3 |Joanne|LA |
3 |Chris |LA |
(2) 我需要这样的东西
(2) I need something like this
loanid|name |address |name |address |name|address|
1 |Jonh |New York |Carl |New York|Henry|Boston|
2 |Robert|Chicago |
3 |Joanne|LA |Chris|LA|
推荐答案
测试数据
DECLARE @TABLE TABLE (loanid INT,name VARCHAR(20),[Address] VARCHAR(20))
INSERT INTO @TABLE VALUES
(1,'John','New York'),(1,'Carl','New York'),(1,'Henry','Boston'),
(2,'Robert','Chicago'),(3,'Joanne','LA'),(3,'Chris','LA')
查询
SELECT loanid
,ISNULL(name1, '') AS name1
,ISNULL(Address1, '') AS Address1
,ISNULL(name2, '') AS name2
,ISNULL(Address2, '') AS Address2
,ISNULL(name3, '') AS name3
,ISNULL(Address3, '') AS Address3
FROM (
SELECT loanid
,'name' + CAST(ROW_NUMBER() OVER (PARTITION BY loanid ORDER BY loanid) AS NVARCHAR(10)) AS Cols
, name AS Vals
FROM @TABLE
UNION ALL
SELECT loanid
,'Address' + CAST(ROW_NUMBER() OVER (PARTITION BY loanid ORDER BY loanid) AS NVARCHAR(10))
, [Address]
FROM @TABLE ) t
PIVOT (MAX(Vals)
FOR Cols
IN (name1, Address1,name2,Address2,name3,Address3)
)P
结果集
╔════════╦════════╦══════════╦═══════╦══════════╦═══════╦══════════╗
║ loanid ║ name1 ║ Address1 ║ name2 ║ Address2 ║ name3 ║ Address3 ║
╠════════╬════════╬══════════╬═══════╬══════════╬═══════╬══════════╣
║ 1 ║ John ║ New York ║ Carl ║ New York ║ Henry ║ Boston ║
║ 2 ║ Robert ║ Chicago ║ ║ ║ ║ ║
║ 3 ║ Joanne ║ LA ║ Chris ║ LA ║ ║ ║
╚════════╩════════╩══════════╩═══════╩══════════╩═══════╩══════════╝
动态列的更新
DECLARE @Cols NVARCHAR(MAX);
SELECT @Cols = STUFF((
SELECT DISTINCT ', ' + QUOTENAME(Cols)
FROM (
SELECT loanid
,'name' + CAST(ROW_NUMBER() OVER (PARTITION BY loanid ORDER BY loanid) AS NVARCHAR(10)) AS Cols
, name AS Vals
FROM @TABLE
UNION ALL
SELECT loanid
,'Address' + CAST(ROW_NUMBER() OVER (PARTITION BY loanid ORDER BY loanid) AS NVARCHAR(10))
, [Address]
FROM @TABLE ) t
GROUP BY QUOTENAME(Cols)
FOR XML PATH(''), TYPE).value('.','NVARCHAR(MAX)'),1,2,'')
DECLARE @Sql NVARCHAR(MAX);
SET @Sql = 'SELECT ' + @Cols + '
FROM (
SELECT loanid
,''name'' + CAST(ROW_NUMBER() OVER
(PARTITION BY loanid ORDER BY loanid) AS NVARCHAR(10)) AS Cols
, name AS Vals
FROM @TABLE
UNION ALL
SELECT loanid
,''Address'' + CAST(ROW_NUMBER() OVER
(PARTITION BY loanid ORDER BY loanid) AS NVARCHAR(10))
, [Address]
FROM @TABLE ) t
PIVOT (MAX(Vals)
FOR Cols
IN (' + @Cols + ')
)P'
EXECUTE sp_executesql @Sql
注意
这不适用于我的答案中给定的示例数据,因为它使用表变量,并且它对动态 sql 不可见,因为它有自己的范围.但此解决方案适用于普通的 sql server 表.
This wouldnt work with the given sample data in my answer, as it uses a table variable and it is not visible to dynamic sql since it has it own scope. but this solution will work on a normal sql server table.
此外,选择列的顺序也会略有不同.
Also the order in which columns are selected will be slightly different.
相关文章