【发布时间】:2017-02-03 22:22:56
【问题描述】:
抱歉,它有点长。我已经完成了代码。
真正的代码涉及用于详细报告的数据桶。我的 cte 块失败了。另一种方法是编写一个 SET 的多个 UPDATE 块并在每个块中加入一个 - 丑陋但有效。
在给定的 cte 块中,无论我将它放在 cte 块的哪个位置,我都只能填充 Hair。在下方的 UPDATE 块中,一切正常。 (在我的实际情况中,我的 cte 连接有大约 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'
【问题讨论】:
-
您需要更新基础表#TempList 而不是正在运行的cte_name。
-
同意@andrews。此外,您的正确脚本可能会有所不同,但这里甚至不需要您的 CTE。您可以通过 JOIN 中的常规 UPDATE 完成完全相同的事情
-
我曾尝试修改您原来的 CTE,但没有成功。我也尝试过使用对我也不起作用的 MERGE。所以最后我想出了使用 PIVOT 的更新版本。请看下面我的回答。你也需要更新重量列吗?
-
是的,我知道这可以通过其他方式实现。我有一个复杂的问题,这是一个(大)简化。 CTE 会自动更新#TempList——这就是它的工作方式。令我震惊的是:a)为什么这不起作用,b)为什么只有头发填充?
-
@ThysCoetzee 我没有注意到你昨天的最后评论。你有机会测试我的 cte 版本吗?性能可以接受吗?
标签: sql-server sql-update common-table-expression