Обновление для переключения логического столбца в одном выражении - PullRequest
2 голосов
/ 22 марта 2019

Как мне объединить в одном sql выражении обоих запросов наиболее эффективным способом?

UPDATE TABLE_A a
SET a.is_active = FALSE
WHERE a.id IN (SELECT id FROM TABLE_B);

И то же самое, но переключатель флаг для оставшихся id s:

UPDATE TABLE_A a
SET a.is_active = TRUE
WHERE a.id NOT IN (SELECT id FROM TABLE_B);

Ответы [ 4 ]

2 голосов
/ 22 марта 2019
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, ни NOT IN каким-либо набором.

И если в table_b.id имеются какие-либо значения NULL, то ни один ваших строк не заканчивается на a.is_active = TRUE, поскольку a.id NOT IN (SELECT id FROM TABLE_B) равен FALSE или NULL, но никогда TRUE в таком случае. NOT IN печально известна для такого рода "ловушек". Связанный:

Этот запрос с EXISTS обновляет все строк. table_a.id IS NULL приводит к is_active = TRUE, как и для других идентификаторов, которых нет в table_b, а значения NULL в table_b.id не имеют значения.

EXISTS также привлекателен, в частности, если в table_b.id может быть (много) повторяющихся значений - лучшая производительность. table_b.id следует индексировать в любом случае.

2 голосов
/ 22 марта 2019

В 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 голосов
/ 22 марта 2019

Ну, вы можете использовать выражение CASE:

UPDATE TABLE_A a
    SET a.is_active = (CASE WHEN a.id IN (SELECT id FROM TABLE_B)
                            THEN FALSE ELSE TRUE
                       END); 

В Postgres вы упростите это до:

UPDATE TABLE_A
    SET is_active = (id IN (SELECT b.id FROM TABLE_B b));
0 голосов
/ 22 марта 2019

Вы можете использовать объединение двух таблиц, а затем оператор 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...