我的UPDATE语句如下:
UPDATE customer
SET forenames=ot.forenames,
surname =
CASE WHEN ot.safeplace IS NULL
THEN 'test SAFEPLACE IS NULL'
ELSE 'test Safeplace IS NOT NULL'
END,
middlename =
CASE WHEN ot.safeplace IS NULL
THEN 'test2 SAFEPLACE IS NULL'
ELSE 'test2 Safeplace IS NOT NULL'
END,
FROM order_transaction ot
WHERE customer.custid = ot.custid
AND ot.trans_orderid = 5678
AND customer.custid = 1234
Run Code Online (Sandbox Code Playgroud)
以上工作.它基本上检查另一个表中的字段是否为NULL,然后相应地更新客户的"姓"和"中间名".如您所见,我重复了两次相同的CASE语句.我的问题是 - 有一种方法可以只指定一次CASE语句吗?
关键是,如果我想根据某个条件更新10个字段,我是否需要包含10个类似的CASE条件?或者可以改进SQL以在WHEN/ELSE子句中只有一个CASE和10个字段更新?
(我使用的是Postgresql 8.2数据库,但我相信上面是标准的SQL).
非常感谢,Rishi
我相信以上是标准的SQL
实际上,事实并非如此.标准SQL没有UPDATE..FROM语法.相反,您需要为每个SET子句使用标量子查询加上另一个子句EXISTS,因此标准语法甚至更重复,例如
UPDATE customer
SET forenames = (
SELECT ot.forenames
FROM order_transaction AS ot
WHERE customer.custid = ot.custid
AND ot.trans_orderid = 5678
),
surname = (
SELECT CASE
WHEN ot.safeplace IS NULL
THEN 'test SAFEPLACE IS NULL'
ELSE 'test Safeplace IS NOT NULL'
END
FROM order_transaction AS ot
WHERE customer.custid = ot.custid
AND ot.trans_orderid = 5678
),
middlename = (
SELECT CASE
WHEN ot.safeplace IS NULL
THEN 'test SAFEPLACE IS NULL'
ELSE 'test Safeplace IS NOT NULL'
END
FROM order_transaction AS ot
WHERE customer.custid = ot.custid
AND ot.trans_orderid = 5678
)
WHERE customer.custid = 1234
AND EXISTS (
SELECT *
FROM order_transaction AS ot
WHERE customer.custid = ot.custid
AND ot.trans_orderid = 5678
);
Run Code Online (Sandbox Code Playgroud)
虽然语法看起来很重复,但优秀的优化器应该能够识别重复并相应地进行优化.当前版本的SQL产品是否真的能够在实践中很好地优化它当然是另一回事.但请考虑一下:如果您选择的SQL产品支持标准语法但实际上没有正确优化它,那么"支持"是否值得?
如果你想使用标准SQL(因为你确实应该IMO :)并想要一个更"紧凑"的语法然后看看MERGE或MERGE(SQL),例如看起来更像这样:
MERGE INTO customer
USING (
SELECT ot.custid, ot.forenames,
CASE
WHEN ot.safeplace IS NULL
THEN 'test SAFEPLACE IS NULL'
ELSE 'test Safeplace IS NOT NULL'
END
FROM order_transaction AS ot
WHERE ot.trans_orderid = 5678
) AS source (custid, forenames, safeplace_narrative)
ON customer.custid = source.custid
AND customer.custid = 1234
WHEN MATCHED THEN
UPDATE
SET forenames = source.forenames,
surname = source.safeplace_narrative,
middlename = source.safeplace_narrative;
Run Code Online (Sandbox Code Playgroud)
如果要在同一查询级别上执行 CASE,则需要重复 CASE,就像在 group by 子句中重复计算列一样。
您的示例查询根本没有揭示您想要执行的操作,您是否真的将所有记录以及每条记录的所有列更新为相同的值(固定文本)。如果您更新以使问题更相关,可能会有更好的答案。
UPDATE customer
SET forenames=ot.forenames,
surname = fixedText,
middlename = fixedText
FROM (select o.*, CASE
WHEN safeplace IS NULL
THEN 'test2 SAFEPLACE IS NULL'
ELSE 'test2 Safeplace IS NOT NULL'
END fixedText
from order_transaction o) ot
WHERE customer.custid = ot.custid
AND ot.trans_orderid = 5678
AND customer.custid = 1234
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
28139 次 |
| 最近记录: |