Postgresql
為每一行顯示用於選擇它的條件的標誌(指示器)
假設我有桌子
foo
。我想使用不同的條件(cond_1
,cond_2
, …,cond_n
-順序很重要)過濾這個表的行,組合在一個析取中,即:SELECT * FROM foo WHERE cond_1 OR cond_2 OR ... OR cond_n;
- 是否可以(在 PostgreSQL 13 中)區分每一行使用哪個條件
cond_i
來選擇它?因為我說順序很重要,所以問題可以重新表述為 - 我想知道cond_i
為每一行選擇行的第一個。現在考慮我
foo
為此目的在一個專欄中,例如selected_by
。
- 是否可以區分每一行使用哪個條件
cond_i
來選擇它並將其儲存在其中selected_by
?(與第一個問題相同,但針對 UPDATE 語句)有兩件事很重要:條件的順序(如前所述);性能(即表
foo
可能有很多行,條件數很少,最多5-10)。
如果您的條件是互斥的(您只關心匹配您控制的訂單的第一個),那麼您可以只使用一列:
SELECT *, CASE WHEN name = 'meatfeast' THEN 'name' WHEN diet = 'vegan' THEN 'diet' END as reason_for_appearing FROM pizza WHERE name = 'meatfeast' OR diet = 'vegan'
您重複您的 where 條件作為案例的單個子句 when,(按照您關心它們的順序)
如果它們不是互斥的,並且您想知道它可能匹配的所有原因,您將需要多個列..
SELECT *, CASE WHEN name = 'john' THEN 'yes' END as because_of_name, CASE WHEN city = 'Chicago' THEN 'yes' END as because_of_city FROM person WHERE name = 'john' OR city = 'chicago'
..除非你想真正參與一個巨大的案例,當所有條件組合(這是2 ^ N,我相信你可以想像)
或者您也可以選擇做某種連接,您可以通過程式方式將其分開,或者使用者可以閱讀
SELECT *, CONCAT( CASE WHEN name = 'john' THEN 'name' END, CASE WHEN city = 'Chicago' THEN ' city' END ) as because_of FROM person WHERE name = 'john' OR city = 'chicago'
我想這取決於你想用它做什麼
您可以計算條件遮罩(例如二進製表示):
CREATE TABLE test (id INT, val INT); INSERT INTO test VALUES (1,1), (1,2), (2,1), (2,2);
SELECT *, (id=1 AND val=1)::INT + 2 * (id<val)::INT + 4 * ((id+val)!=3)::INT conditions_mask_bin, (id=1 AND val=1)::INT + 10 * (id<val)::INT + 100 * ((id+val)!=3)::INT conditions_mask_dec FROM test WHERE (id=1 AND val=1) OR (id<val) OR ((id+val)!=3);
編號 | 值 | conditions_mask_bin | conditions_mask_dec -: | --: | ------------------: | ------------------: 1 | 1 | 5 | 101 1 | 2 | 2 | 10 2 | 2 | 4 | 100
db<>在這裡擺弄