簡體   English   中英

在 Postgres 中:在多個值上使用“IS DISTINCT FROM”的最簡潔方法是什么?

[英]In Postgres: What is the most concise way to use `IS DISTINCT FROM` on multiple values?

我正在嘗試查找具有枚舉列的所有行,該列要么是 NULL,要么與給定的一組枚舉值不同。 我可以用很多IS DINSTINCT FROM調用來做到這一點,但它真的很冗長,我寧願使用NOT IN()語法,但NULL會拋棄它。

這是我想在 SQL 中做的一個例子,來自這個小提琴: http://sqlfiddle.com/#!17/dfae4d/8


    CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
    CREATE TABLE people (
        name text,
        current_mood mood,
        current_mood_as_text varchar
    );
    insert into people values('Mr Happy', 'happy', 'happy');
    insert into people values('Mr Sad', 'sad', 'sad');
    insert into people values('Mr Null', NULL, NULL);

    -- This doesn't return MrUnknown because of the NULL value:
    select * from people where current_mood NOT IN ('happy');

    -- This works great, and includes Mr Null:
    select * from people where current_mood IS DISTINCT FROM 'happy';

    -- But If I want to start comparing to multiple moods, it gets more verbose fast:
    SELECT * FROM people 
    WHERE current_mood IS DISTINCT FROM 'happy' AND
    current_mood IS DISTINCT FROM 'sad';

    -- You can't write this, but it's kinda what I want:
    -- SELECT * FROM people 
    -- WHERE current_mood IS DISTINCT FROM ('happy', 'sad');

    -- For the non enum column, I could do this to make my intention and code clear and concise
    SELECT * FROM people 
    WHERE coalesce(current_mood_as_text, '') NOT IN ('happy', 'sad');

    -- But if I write this, I get an error because '' is not a valid enum value
    -- SELECT * FROM people 
    -- WHERE coalesce(current_mood, '') NOT IN ('happy', 'sad');

還有另一種方法可以使這種多重比較更簡潔嗎?

使用coalesce()的解決方案:

select * 
from people 
where coalesce(current_mood not in ('happy', 'sad'), true)

SQLFiddle。

還有一種方式:


SELECT * FROM people 
WHERE NOT EXISTS (
  SELECT FROM (VALUES ('happy'::mood), ('sad')) v(m)
  WHERE people.current_mood = v.m
);

Cleanest(IMO) 方法是在 CTE 中使用VALUES()並對該表表達式執行NOT EXISTS()


WITH m(m) AS ( VALUES( 'happy'::mood) )
SELECT *
FROM people p
WHERE NOT EXISTS (
        SELECT * FROM m
        WHERE m.m = p.current_mood
        );

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM