[英]Select records that match at least all items in a list
假設我有以下數據庫表:
ID | Name | Type | Value|
--- --------- ---------- ------
1 | First | A | 10 |
2 | First | B | 20 |
3 | First | C | 30 |
4 | First | D | 40 |
5 | Second | A | 10 |
6 | Second | B | 20 |
並返回上一個查詢:
ID | Name | Type | Value|
--- --------- ---------- ------
1 | Third | A | 10 |
2 | Third | B | 20 |
3 | Third | C | 30 |
我的問題是:什么是查詢第一個表並獲取至少具有上一個查詢中返回的所有類型的所有記錄的最佳方法?
在上面的示例中,名稱“ Third”的類型為ABC。使用這些作為列表,我只想檢索“ First”記錄(因為“ First”具有ABCD)而不是“ Second”(因為“ Second”具有只有AB-缺少C)。
IN語句匹配eveything,並且我希望查詢至少匹配“類型”列表中的所有項目。 該列表不一定來自sql語句,但可以提供
編輯:我正在使用MySQL
包括兩個數據庫的同一查詢的兩個變體。
SELECT main.*
FROM main
LEFT JOIN (
SELECT name, json_arrayagg(type) as type
FROM main
GROUP BY name
) AS main_agg USING(name)
WHERE EXISTS (
SELECT 1
FROM (
select json_arrayagg(type) as type
from query
group by name
) AS query_agg
WHERE JSON_CONTAINS(main_agg.type, query_agg.type)
)
WITH main_agg AS
(
SELECT name, array_agg(type) "type"
FROM main
GROUP BY name
)
SELECT main.*
FROM main
JOIN main_agg USING(name)
WHERE EXISTS (
SELECT 1
FROM (select array_agg(type) "type" from query group by name) query_agg
WHERE main_agg."type" @> query_agg."type"
)
@>
( contains operator )與查詢進行比較 (適用於MySQL或PostgreSQL)
CREATE TABLE main
(ID int, Name varchar(6), Type varchar(1), Value int)
;
INSERT INTO main
(ID, Name, Type, Value)
VALUES
(1, 'First', 'A', 10),
(2, 'First', 'B', 20),
(3, 'First', 'C', 30),
(4, 'First', 'D', 40),
(5, 'Second', 'A', 10),
(6, 'Second', 'B', 20)
;
CREATE TABLE query
(ID int, Name varchar(5), Type varchar(1), Value int)
;
INSERT INTO query
(ID, Name, Type, Value)
VALUES
(1, 'Third', 'A', 10),
(2, 'Third', 'B', 20),
(3, 'Third', 'C', 30)
;
在標准SQL中,你可以做到這一點的join
,並group by
與一些過濾。 以下假設type
s對於每個表中的每個名稱都是唯一的:
with prevq as (
. . .
)
select t.name
from t join
prevq
on t.type = prevq.type
group by t.name
having count(*) = (select count(*) from prevq);
編輯:
MySQL不支持CTE(8.0之前)。 這很容易做到:
select t.name
from t join
(<your query here>) prevq
on t.type = prevq.type
group by t.name
having count(*) = (select count(*) from (<your query here>) prevq);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.