簡體   English   中英

按多列和多行條件查找 sql 查詢

[英]Find by multiple columns and rows criteria sql query

我在 PostgreSQL 中有 Paths 和 Criteria 表。 路徑具有多個應滿足的條件才能被選擇。

帶有 ( id , name ) 的路徑表,帶有 ( id , key , value , path_id ) 的標准表

我需要創建一個 SQL 查詢來選擇滿足兩個或多個條件輸入(例如,年齡 30 歲和男性)的單個路徑。 我已經嘗試過下面給出的ANY

SELECT p.*, array_agg(c.*) as criteria 
FROM paths as p 
INNER JOIN criteria as c ON c.path_id = p.id 
WHERE (c.key, c.value) = ANY (array[
    ("age","30"),
    ("gender","male") 
    ])
GROUP BY p.id

但是只要滿足任何一個標准( whether age = 30 or sex = "male"而不是兩者),這都會得到一條路徑。 我用ALL替換了ANY但這根本不返回任何值。

當您處理鍵/值對時,將條件聚合到 JSON 對象中並使用 Postgres 的 json 函數來選擇您想要的對象可能會更容易:

select p.*, c.*
from paths as p 
  join (
     select path_id, jsonb_object_agg(key, value) as all_criteria
     from criteria
     group by path_id
     having jsonb_object_agg(key, value) @> '{"age": "30", "gender": "male"}'
  )  c on c.path_id = p.id 

在線示例

如果我正確地跟隨您,您需要將條件移動到having子句而不是where子句。 此外,如果您想要滿足所有條件的記錄,那么您需要單獨檢查每個條件:

select p.*, array_agg(c.key || ':' || c.value) as criteria
from paths p
inner join criteria c on c.path_id = p.id
group by p.id
having
    count(*) filter(where c.key = 'age' and c.value = '30') > 0
    and count(*) filter(where c.key = 'gender' and c.value = 'male') > 0

這也可以用兩個EXISTS條件表示,這應該是一個退出高效的查詢,在criteria(path_id, key, value)上有一個索引(但是你失去了聚合所有標准的能力):

select p.*
from paths p
where
    exists (
        select 1 
        from criteria c
        where c.path_id = p.id and c.key = 'age' and c.value = '30'
    )
    and exists (
        select 1 
        from criteria c
        where c.path_id = p.id and c.key = 'gender' and c.value = 'male'
    )

暫無
暫無

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

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