如何以最有效的方式在单个 sql 语句中组合?
UPDATE TABLE_A a
SET a.is_active = FALSE
WHERE a.id IN (SELECT id FROM TABLE_B);
和其余id
的标志相同,但 togggle :
UPDATE TABLE_A a
SET a.is_active = TRUE
WHERE a.id NOT IN (SELECT id FROM TABLE_B);
答案 0 :(得分:2)
好吧,您可以使用UPDATE TABLE_A a
SET a.is_active = (CASE WHEN a.id IN (SELECT id FROM TABLE_B)
THEN FALSE ELSE TRUE
END);
表达式:
UPDATE TABLE_A
SET is_active = (id IN (SELECT b.id FROM TABLE_B b));
在Postgres中,您可以将其简化为:
apt-get
答案 1 :(得分:2)
在Postgres中,您可以在LEFT JOIN
语句中使用以下语法使用UPDATE
:
UPDATE a
SET a.is_active = CASE WHEN b.id IS NULL THEN FALSE ELSE TRUE
FROM TABLE_A a
LEFT JOIN TABLE_B b ON a.id = b.id
答案 2 :(得分:2)
UPDATE table_a a
SET is_active = NOT EXISTS (SELECT FROM table_b b WHERE b.id = a.id);
假设两个id
列均为 NOT NULL
。
否则,table_a.id IS NULL
既不是NULL
也不是IN
任何集合,因此在您的原始行中根本没有{strong>未更新的行。
如果NOT IN
中有任何NULL
个值,则您的行中的无都以table_b.id
结尾,因为a.is_active = TRUE
是{{ 1}}或a.id NOT IN (SELECT id FROM TABLE_B)
,但在这种情况下永远不要使用FALSE
。 NULL
因这种“陷阱”而臭名昭著。相关:
带有TRUE
的查询会更新所有行。 NOT IN
的结果为EXISTS
,就像在table_a.id IS NULL
中找不到的其他ID一样,is_active = TRUE
中的NULL值也没有任何区别。
table_b
也很有吸引力,特别是如果table_b.id
中可以有(很多)重复值-则性能更好。在任何情况下都应为EXISTS
编制索引。
答案 3 :(得分:0)
您可以在两个表上使用联接,然后使用case语句确定表B中是否存在值:
CREATE TABLE #TABLE_A (Id int, is_active bit)
CREATE TABLE #TABLE_B (Id int)
INSERT INTO #Table_A
VALUES (1, NULL)
,(2, NULL)
,(3, NULL)
,(4, NULL)
INSERT INTO #TABLE_B
VALUES (1),(3)
SELECT * FROM #TABLE_A
UPDATE a
SET is_active = (CASE WHEN b.id IS NULL THEN 1 ELSE 0 END)
FROM #TABLE_A a
LEFT OUTER JOIN #TABLE_B b
ON a.id = b.Id
SELECT * FROM #TABLE_A