对不起,这是一个更长的。我把代码完成了。
真实代码涉及详细报告的数据桶。我的cte块失败了。另一种方法是编写一个SET的一些UPDATE块和一个连接 - 丑陋但有效。
在给定的cte块中,无论我把它放在cte块中的什么地方,我都只能填充Hair。在更低的UPDATE块中,一切都运行良好。 (在我的实际情况中,我的cte join有大约140k记录,每次更新都会返回一个随机数量的记录:/)
我这次犯了什么愚蠢的错误?
谢谢, 蒂斯
IF OBJECT_ID('tempdb..#TempList') IS NOT NULL
DROP TABLE #TempList
IF OBJECT_ID('tempdb..#TempValues') IS NOT NULL
DROP TABLE #TempValues
CREATE TABLE #TempList (
Name NVARCHAR(20),
Hair NVARCHAR(20),
Height NVARCHAR(20),
Job NVARCHAR(20)
)
CREATE TABLE #TempValues (
Name NVARCHAR(20),
VariableName NVARCHAR(20) ,
VariableValue NVARCHAR(20)
)
INSERT INTO #TempList
( Name ,
Hair ,
Height,
Job
)
VALUES
('Fred', NULL, NULL, NULL),
('Wilma', NULL, NULL, NULL),
('Barney', NULL, NULL, NULL),
('Betty', NULL, NULL, NULL),
('Pebbles', NULL, NULL, NULL),
('Bammbamm', NULL, NULL, NULL)
INSERT INTO #TempValues
( Name ,
VariableName ,
VariableValue
)
VALUES
('Fred', 'Hair','Dark'),
('Fred', 'Height','6-1'),
('Fred', 'Weight','220'),
('Wilma', 'Hair','Red'),
('Wilma', 'Height','5-5'),
('Wilma', 'Weight','125'),
('Barney', 'Hair','Blond'),
('Barney', 'Weight','195'),
('Barney', 'Job','Worker'),
('Barney', 'Married','Yes'),
('Betty', 'Hair','Dark'),
('Betty', 'Height','5-3'),
('Pebbles', 'Hair','Red')
;WITH cte_name AS (
SELECT TL.Name ,
TL.Hair ,
TL.Height ,
TL.Job ,
TV.VariableName ,
TV.VariableValue
FROM #TempList TL
JOIN #TempValues TV ON TV.Name = TL.Name
)
UPDATE cte_name
SET
cte_name.Height =
CASE cte_name.VariableName
WHEN 'Height' THEN cte_name.VariableValue
END ,
cte_name.Hair =
CASE cte_name.VariableName
WHEN 'Hair' THEN cte_name.VariableValue
END ,
cte_name.Job =
CASE cte_name.VariableName
WHEN 'Job' THEN cte_name.VariableValue
END
SELECT * FROM #TempList
SELECT * FROM #TempValues
--UPDATE #TempList SET Hair = NULL , Height = NULL , Job = NULL
-- Run either the top UPDATE or these updates
UPDATE #TempList
SET Height = TV.VariableValue
FROM #TempList TL
JOIN #TempValues TV ON TV.Name = TL.Name
WHERE TV.VariableName = 'Height'
UPDATE #TempList
SET Hair = TV.VariableValue
FROM #TempList TL
JOIN #TempValues TV ON TV.Name = TL.Name
WHERE TV.VariableName = 'Hair'
UPDATE #TempList
SET Job = TV.VariableValue
FROM #TempList TL
JOIN #TempValues TV ON TV.Name = TL.Name
WHERE TV.VariableName = 'Job'
答案 0 :(得分:1)
这将使其工作,完全替换现有的cte与下面的一个:
;
with cte as (
select Name,[Hair],[Height],[Job] from #TempValues tv
pivot (min(VariableValue) for VariableName in ([Hair],[Height],[Job]) ) pvt
)
UPDATE t
SET
t.Height = ISNULL(cte.Height, t.Height),
t.Hair = ISNULL(cte.Hair, t.Hair),
t.Job = ISNULL(cte.Job, t.Job)
from #TempList t
join cte on cte.Name = t.Name
对您的数据运行上述查询后,select * from #TempValues
会生成以下输出(我还在ID int not null identity(1,1)
表中添加了#TempList
):
说明:
首先,我们使用PIVOT将垂直属性/值转换为水平列,因此select * from cte
会产生以下结果:
然后我们使用ISNULL(...)过滤掉UPDATE调用中的NULL值。
如果您还需要权重列,只需在[Job]
子句和{更新部分}中的pivot(...)
之后添加。
希望这有帮助。
PS。 2/15/2017添加此非工作UPDATE版本以供参考:
UPDATE t
SET
t.Height =
CASE tv.VariableName
WHEN 'Height' THEN tv.VariableValue
END ,
t.Hair =
CASE tv.VariableName
WHEN 'Hair' THEN tv.VariableValue
END ,
t.Job =
CASE tv.VariableName
WHEN 'Job' THEN tv.VariableValue
END
FROM #TempList t
JOIN #TempValues TV ON TV.Name = t.Name
注意,这是没有CTE的直接UPDATE
,如果我删除#TempValues
JOIN并将JOIN添加到CTE,结果是相同的:它只更新每个Name的第一个属性。如果您在每个名称的INSERT ... VALUES (...)
列表中切换头发和高度,则将更新高度而不是头发。
我还没发现它为什么会这样。如果我找到了什么,我会在这里发帖。