我需要获取一些查询结果并将其展平以获得报告。
DECLARE @randomTable table (ID int, OtherID int, Val varchar(max))
insert into @randomTable(ID, OtherID, Val)
values (1, 100, 'Some Value 1'), (2, 100, 'Some Other 2'),
(3, 100, 'Some Value 3'), (4, 200, 'Some Other 4'),
(5, 200, 'Some Value 5'), (6, 300, 'Some Other 6'),
(7, 300, 'Some Value 7'), (8, 300, 'Some Other 8'),
(9, 400, 'Some Value 9'), (10, 500, 'Some Other 10')
select OtherID, Val from @randomTable
结果:
-- 100 | Some Value 1
-- 100 | Some Other 2
-- 100 | Some Value 3
-- 200 | Some Other 4
-- 200 | Some Value 5
-- 300 | Some Other 6
-- 300 | Some Value 7
-- 300 | Some Other 8
-- 400 | Some Value 9
-- 500 | Some Other 10
是否有SQL方法可以将其更改为选择:
-- 100 | Some Value 1 | Some Other 2 | Some Value 3
-- 200 | Some Other 4 | Some Value 5
-- 300 | Some Other 6 | Some Value 7 | Some Other 8
-- 400 | Some Value 9
-- 500 | Some Other 10
注意:以上是一个例子。我的真实数据不是静态的。此外,在我的实际数据中,OtherID
是字符串值,Val
值是存储为varbinary的图像。
我当然要限制我允许的列数。我想最多5个(之后我可以丢失额外的行)。
有没有办法做到这一点?
答案 0 :(得分:4)
;WITH cte
AS (SELECT OtherID,
Val,
ROW_NUMBER() OVER (PARTITION BY OtherID ORDER BY (SELECT 0)) rn
FROM @randomTable)
SELECT OtherID,
[1],
[2],
[3],
[4],
[5]
FROM cte PIVOT( MAX(Val) FOR rn IN ([1], [2], [3], [4], [5])) AS PivotTable;
要提供一些解释,SELECT * FROM cte
会返回以下内容。
OtherID Val rn
----------- -------------------- ---
100 Some Value 1 1
100 Some Other 2 2
100 Some Value 3 3
200 Some Other 4 1
200 Some Value 5 2
300 Some Other 6 1
300 Some Value 7 2
300 Some Other 8 3
400 Some Value 9 1
500 Some Other 10 1
我添加了row_number
列,以便在PIVOT
中提供一些内容。请注意,每个OtherID,rn
组合有一行或一行。 PIVOT
语句等同于以下内容。
SELECT OtherID,
MAX(CASE WHEN rn=1 THEN Val END) AS [1],
MAX(CASE WHEN rn=2 THEN Val END) AS [2],
MAX(CASE WHEN rn=3 THEN Val END) AS [3],
MAX(CASE WHEN rn=4 THEN Val END) AS [4],
MAX(CASE WHEN rn=5 THEN Val END) AS [5]
FROM cte
GROUP BY OtherID /*You want one row per OtherID */
答案 1 :(得分:2)
我不确定您是要转入列还是将结果连接到一个列(用于报告)。
如果您正在寻找动态支点,请查看此处的文章:link及其后续评论。如果您能够限制数据透视中涉及的列,则可以使用数据透视运算符(如前所述)并获得更好的性能。
如果您希望将行连接到列,请查看以下查询。利用XML PATH确实会对特殊字符(<& etc.等)产生一些影响,因此如果这适用于您的情况,请回发一下,我们可以扩展这个简单的示例。
-- if you have normalized type table use it instead of this cte
;with c_distinct (OtherId)
as ( select distinct OtherId
from @randomTable
)
select OtherId,
stuff(c, 1, 2, '')
from c_distinct cd
cross
apply ( select '| ' + Val
from @randomTable rt
where cd.OtherId = rt.OtherId
for xml path('')
) d(c)
答案 2 :(得分:0)
你要求的是非规范化,对吧?
我认为你的问题在这里得到解答:Denormalizing Data (Maybe A Pivot?)