我在sql server数据库中有以下关系:
假设我想在关系中做一些修改。我想删除CPU_TYPE表并在计算机表中添加一列'cpu'。
现在我想使用sql server中的'with'子句来查询从两个表连接的数据,并执行update语句来更新计算机表。
这个sql server查询:
SELECT COMPUTER.compID, COMPUTER.serialNo, COMPUTER.cpuId,
CPU_TYPE.name, CPU_TYPE.cpuSpeed, COMPUTER.cpu
FROM COMPUTER LEFT OUTER JOIN
CPU_TYPE ON COMPUTER.cpuId = CPU_TYPE.cpuId
结果如下:
现在我将使用'with'子句创建一个数据集,如下所示:
with ds as
(
SELECT COMPUTER.compID, COMPUTER.serialNo, COMPUTER.cpuId,
CPU_TYPE.name, CPU_TYPE.cpuSpeed, COMPUTER.cpu
FROM COMPUTER LEFT OUTER JOIN
CPU_TYPE ON COMPUTER.cpuId = CPU_TYPE.cpuId
)
update ds set cpu = name +', '+ cpuSpeed;
结果如下:
查询成功执行但问题是COMPUTER表没有改变! 如何解决这个问题?
答案 0 :(得分:1)
你的代码很好。您的数据已关闭。 CPUSpeed
为NULL
,因此连接的结果始终为NULL
。因此,请使用coalesce()
:
with ds as (
SELECT COMPUTER.compID, COMPUTER.serialNo, COMPUTER.cpuId,
CPU_TYPE.name, CPU_TYPE.cpuSpeed, COMPUTER.cpu
FROM COMPUTER LEFT OUTER JOIN
CPU_TYPE
ON COMPUTER.cpuId = CPU_TYPE.cpuId
)
update ds
set cpu = name +', '+ coalesce(cpuSpeed, '');
答案 1 :(得分:1)
我相信很多人会在答案中注明,你不 使用公用表表达式来完成此更新。
那说,但是,你可以(如果你想练习你的CTE技能):
WITH cte AS
(
SELECT c1.compID, c2.name, c2.cpuSpeed
FROM [COMPUTER] AS c1
LEFT OUTER JOIN [CPU_TYPE] AS c2
ON ( comp.cpuId = c2.cpuId )
)
UPDATE [COMPUTER]
SET cpu = cte.name + ', ' + cte.cpuSpeed
FROM [COMPUTER] AS comp
INNER JOIN cte ON ( comp.compId = cte.compId )
如果您想过滤CTE结果,那么您可以在CTE中添加WHERE子句,如:
WHERE c1.cpuId IS NOT NULL
或其他任何事情。
更新
如果您确实在cpuSpeed
列中有NULL数据,那么您可能需要考虑以下SET
语句而不是上面列出的SET
:
SET cpu = cte.name + Coalesce(', ' + cte.cpuSpeed, '')
......或者:
SET cpu = cte.name + IsNull(', ' + cte.cpuSpeed, '')
这样,如果cpuSpeed
为NULL,那么您仍然拥有来自name
列的数据,而不会在末尾附加逗号(“,”);如果name
也为NULL(或NULL为cpuSpeed
),则cpu
将设置为NULL。
请记住,您可以随时为CTE添加更具保护性的过滤器,例如:
WHERE c1.cpuId IS NOT NULL AND c2.name IS NOT NULL
当然,您应该调整SQL以满足您的特定要求。
我希望这会有所帮助。祝你好运!
答案 2 :(得分:0)
试试这个而不是使用CTE。
UPDATE COMPUTER
SET cpu = name + ', ' + cpuSpeed
FROM COMPUTER C1 LEFT OUTER JOIN
CPU_TYPE ON C1.cpuId = CPU_TYPE.cpuId