我认为这是一个相当简单的查询似乎比我预期的要复杂一点。
我有两张桌子。与一对多的关系。我想要做的是表2返回的任何记录,我希望它在一个单独的列中。我已经设法在以下查询中使用相对较小的数据并知道第二个表返回的内容。
示例数据
DECLARE @TABLE1 TABLE(UserID INT,Episode INT ,[Value] VARCHAR(100))
INSERT INTO @TABLE1 VALUES
(1, 1,'VALUE 1-1'),(1, 2,'VALUE 1-2')
DECLARE @TABLE2 TABLE(UserID INT,Episode INT ,[Details] VARCHAR(100))
INSERT INTO @TABLE2 VALUES
(1, 1,'Details 1'),(1, 1,'Details 2'),(1, 2,'Details 1'),(1, 2,'Details 2')
简单加入
SELECT ONE.UserID
, ONE.Episode
, ONE.Value
, TWO.Details
FROM @TABLE1 ONE INNER JOIN @TABLE2 Two
ON ONE.UserID = TWO.UserID
AND ONE.Episode = TWO.Episode
╔════════╦═════════╦═══════════╦═══════════╗
║ UserID ║ Episode ║ Value ║ Details ║
╠════════╬═════════╬═══════════╬═══════════╣
║ 1 ║ 1 ║ VALUE 1-1 ║ Details 1 ║
║ 1 ║ 1 ║ VALUE 1-1 ║ Details 2 ║
║ 1 ║ 2 ║ VALUE 1-2 ║ Details 1 ║
║ 1 ║ 2 ║ VALUE 1-2 ║ Details 2 ║
╚════════╩═════════╩═══════════╩═══════════╝
在这种情况下,我想PIVOT
详细信息列。我设法用一个非常简单的PIVOT查询做如下
PIVOT查询
SELECT * FROM
(
SELECT ONE.UserID
, ONE.Episode
, ONE.Value
, TWO.Details
FROM @TABLE1 ONE INNER JOIN @TABLE2 Two
ON ONE.UserID = TWO.UserID AND ONE.Episode = TWO.Episode)Q
PIVOT (MAX(Details)
FOR Details
IN ([Details 1], [Details 2]))p
╔════════╦═════════╦═══════════╦═══════════╦═══════════╗
║ UserID ║ Episode ║ Value ║ Details 1 ║ Details 2 ║
╠════════╬═════════╬═══════════╬═══════════╬═══════════╣
║ 1 ║ 1 ║ VALUE 1-1 ║ Details 1 ║ Details 2 ║
║ 1 ║ 2 ║ VALUE 1-2 ║ Details 1 ║ Details 2 ║
╚════════╩═════════╩═══════════╩═══════════╩═══════════╝
这正是我想要的,从列中的表2中返回的所有记录都命名为Details 1
,Details 2
和Details 3
等等......
在这种情况下,它起作用,因为数据重新调整为字符串为“详细信息1”,“详细信息2”和“详细信息3”。
但是,当我不知道将从table2返回多少行时,我将努力转移那些数据。
另一个更重要的事情是,从表2返回的数据是Large Text values
,由连接的几列组成。
我试图遵循 this , this 和 this 问题中给出的逻辑但没有快乐。
任何帮助任何指针在正确的方向非常感谢,提前谢谢你。
答案 0 :(得分:6)
也许我错过了一些东西,但你应该能够隐藏数据,但你需要实现row_number()
来帮助生成列。
关键是使用类似的查询:
SELECT ONE.UserID,
ONE.Episode,
ONE.Value,
TWO.Details,
'Details'
+cast(row_number() over(partition by one.userid, one.episode
order by two.details) as varchar(10)) seq
FROM TABLE1 ONE
INNER JOIN TABLE2 Two
ON ONE.UserID = TWO.UserID
AND ONE.Episode = TWO.Episode
这将为新列名创建一个唯一的序列,然后您可以应用PIVOT:
select userid, episode,
value,
details1,
details2
from
(
SELECT ONE.UserID,
ONE.Episode,
ONE.Value,
TWO.Details,
'Details'
+cast(row_number() over(partition by one.userid, one.episode
order by two.details) as varchar(10)) seq
FROM TABLE1 ONE
INNER JOIN TABLE2 Two
ON ONE.UserID = TWO.UserID
AND ONE.Episode = TWO.Episode
) d
pivot
(
max(details)
for seq in (Details1, Details2)
) piv;
见SQL Fiddle with Demo。然后,您可以将其转换为动态SQL:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME('Details'+cast(seq as varchar(10)))
from
(
select
row_number() over(partition by one.userid, one.episode
order by two.details) seq
FROM TABLE1 ONE
INNER JOIN TABLE2 Two
ON ONE.UserID = TWO.UserID
AND ONE.Episode = TWO.Episode
) d
group by seq
order by seq
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT userid, episode, value, ' + @cols + '
from
(
SELECT ONE.UserID,
ONE.Episode,
ONE.Value,
TWO.Details,
''Details''
+cast(row_number() over(partition by one.userid, one.episode
order by two.details) as varchar(10)) seq
FROM TABLE1 ONE
INNER JOIN TABLE2 Two
ON ONE.UserID = TWO.UserID
AND ONE.Episode = TWO.Episode
) x
pivot
(
max(details)
for seq in (' + @cols + ')
) p '
execute sp_executesql @query;
见SQL Fiddle with Demo。给你结果:
| USERID | EPISODE | VALUE | DETAILS1 | DETAILS2 |
|--------|---------|-----------|-----------|-----------|
| 1 | 1 | VALUE 1-1 | Details 1 | Details 2 |
| 1 | 2 | VALUE 1-2 | Details 1 | Details 2 |