ID COLA
-----------------------
A value1
B value1
C value1
ID DETAIL_ID COL_X COL_Y
A 0 foo foo
A 1 bar bar
B 0 foo foo
我的预期就像是
ID COLA COL_X_0 COL_X_1 COL_Y_0 COL_Y_1
A value1 foo bar foo bar
B value1 foo NULL foo NULL
C value1 NULL NULL NULL NULL
这意味着表B的行将是基于DETAIL_ID列的列值。
我尝试为此编写查询,但由于以下内容无法成功。 DetailID值的数量不会是fixed-length。这意味着我不能对列的名称进行硬编码。
答案 0 :(得分:1)
这将给出您描述的确切输出,如果需要,您可以添加更多列
DECLARE @a table (id char, cola varchar(10))
DECLARE @b table (id char, detail_id int, colx char(3), coly char(3))
INSERT @a values('A', 'value1'),('B', 'value2'),('C','value3')
INSERT @b values('A', 0, 'foo', 'foo'),('A', 1, 'bar', 'bar'),
('B',0, 'foo','foo')--,('A', 2, 'bar', 'bar') -- add this for extra columns
CREATE TABLE ##t(id char, detail_id tinyint, colvalue char(3), col varchar(8), cola varchar(10))
DECLARE @columns varchar(max)=''
DECLARE @sqlstring varchar(1000)
;WITH a as (
SELECT a.id, a.cola, b.detail_id, colx, coly,
'col_x_' + cast(detail_id as varchar) col_a,
'col_y_' + cast(detail_id as varchar) col_b
FROM @a a LEFT JOIN @b b on a.id = b.id
)
INSERT ##t
SELECT id, detail_id, colx, col_a, cola FROM a
UNION
SELECT id, detail_id, coly, col_b, cola FROM a
ORDER BY 4,2
SELECT @columns = coalesce(@columns, '') +',[' + col + ']'
FROM (
SELECT DISTINCT col, detail_id FROM ##t where not col is null
) a
SET @columns = stuff(@columns, 1,1,'')
SET @sqlstring =
'SELECT * FROM (
SELECT id, cola, col, colvalue FROM ##t
) b
PIVOT(max(colvalue) FOR col
in(
'+@columns+'))AS p order by 1'
EXEC(@sqlstring)
DROP TABLE ##t
答案 1 :(得分:0)
只需在B.DETAIL_ID == A.ID上连接表A和B.或者这太简单了?
答案 2 :(得分:0)
SQL查询必须指定结果集的列。这是SQL的基础。即使PIVOT要求您的查询在将列发送到RDBMS之前指定列。
由于这个原因,创建一个按行描述的列返回行的查询很困难且容易出错,并且可以根据需要调整任意数量的列。
处理动态列必须分为两个步骤。
一种选择是使两个阶段成为:
另一个选择是使两个阶段成为: