使用父表和子表的连接我得到这样的结果
select
a.id, a.pname, b.childname
from
parentinfo a
right join
childinfo b on a.id = b.pid
输出:
id pname childname
--------------------------
1 Parent1 p1child1
1 Parent1 p1child2
1 Parent1 p1child3
2 Parent2 p2child1
2 Parent2 p2child2
3 Parent2 p3child1
3 Parent3 p3child2
3 Parent3 p3child3
3 Parent3 p3child4
4 Parent4 p4child1
4 Parent4 p4child2
4 Parent4 p4child3
但是,子项应显示为列,并且一个父项应仅显示一次。
可以有任意数量的孩子。
我想显示如下结果:
id pname child1 child2 child3 child4
------------------------------------------------------
1 parent1 p1child1 p1child2 p1child3
2 parent2 p2child1 p2child2
3 parent3 p3child1 p3child2 p3child3 p3child4
4 parent4 p4child1 p4child2 p4child3
如何实现这一目标?使用数据透视表或任何其他方法?
此查询将所有行转换为列
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(childname)
FROM
(SELECT *
FROM parentinfo a
RIGHT JOIN childinfo b ON a.id = b.pid) tt
GROUP BY childname, id
ORDER BY id
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT ' + @cols + ' from
(
select value, ColumnName
from yourtable
) x
pivot
(
max(value)
for ColumnName in (' + @cols + ')
) p '
execute(@query)
答案 0 :(得分:0)
以下是使用动态交叉表的一种方法:
生成样本数据
use tempdb;
CREATE TABLE yourtable(
id INT,
pname VARCHAR(20),
childname VARCHAR(20)
)
INSERT INTO yourtable VALUES
(1, 'Parent1', 'p1child1'),
(1, 'Parent1', 'p1child2'),
(1, 'Parent1', 'p1child3'),
(2, 'Parent2', 'p2child1'),
(2, 'Parent2', 'p2child2'),
(3, 'Parent3', 'p3child1'),
(3, 'Parent3', 'p3child2'),
(3, 'Parent3', 'p3child3'),
(3, 'Parent3', 'p3child4'),
(4, 'Parent4', 'p4child1'),
(4, 'Parent4', 'p4child2'),
(4, 'Parent4', 'p4child3');
动态交叉表
DECLARE @maxNoChildren INT
DECLARE @sql1 VARCHAR(4000) = ''
DECLARE @sql2 VARCHAR(4000) = ''
DECLARE @sql3 VARCHAR(4000) = ''
SELECT TOP 1 @maxNoChildren = COUNT(*) FROM yourtable GROUP BY id ORDER BY COUNT(*) DESC
SELECT @sql1 =
'SELECT
id
,pname
'
SELECT @sql2 = @sql2 +
' ,MAX(CASE WHEN RN = ' + CONVERT(VARCHAR(5), N) + ' THEN childname END) AS ' + QUOTENAME('child' + CONVERT(VARCHAR(5), N)) + CHAR(10)
FROM(
SELECT TOP(@maxNoChildren)
ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
FROM sys.columns a
--CROSS JOIN sys.columns b
)T(N)
ORDER BY N
SELECT @sql3 =
'FROM(
SELECT *,
RN = ROW_NUMBER() OVER(PARTITION BY id ORDER BY (SELECT NULL))
FROM yourtable
)t
GROUP BY id, pname
ORDER BY id'
PRINT(@sql1 + @sql2 + @sql3)
EXEC (@sql1 + @sql2 + @sql3)
<强>结果强>
| id | pname | child1 | child2 | child3 | child4 |
|----|---------|----------|----------|----------|----------|
| 1 | Parent1 | p1child1 | p1child2 | p1child3 | (null) |
| 2 | Parent2 | p2child1 | p2child2 | (null) | (null) |
| 3 | Parent3 | p3child1 | p3child2 | p3child3 | p3child4 |
| 4 | Parent4 | p4child1 | p4child2 | p4child3 | (null) |