SQL - 检查列表中的值是否不存在于 table 和 return 布尔值中
SQL - check if a value in a list does not exist in table and return boolean accordingly
我有一个由 3 tables
组成的简单数据库模式
用户
编号
名字
预科
文档
编号
连续剧
User_Document(加入table)
user_id
document_id
我想检查连接中是否存在列表(Document.serial 的列表)的所有项目 table(User_Document) 然后 return 真
如果至少一个不存在,它应该 return false
有我当前的查询
SELECT CASE WHEN EXISTS (
SELECT *
FROM user_document ud
INNER JOIN document d ON d.id= ud.document_id
INNER JOIN user u ON u.id = ud.user_id
where u.matricule='123'
and d.serial in ('#1' ,'#2' , '#3')
)
THEN TRUE
ELSE FALSE
END
这不起作用,因为它 return 始终为真,即使列表中的单个项目不存在于联接中 table
我在 PostgreSQL 下
非常感谢
SELECT
D.*,
(CASE WHEN (SELECT 1 FROM USER_DOCUMENT
WHERE D.ID = UD.DOCUMENT_ID LIMIT 1) = 1 THEN TRUE ELSE FALSE END)
FROM DOCUMENT D
试试这个:
SELECT bool_and(ud.document_id is not null) as all_match,
bool_or(ud.documnet_id is not null) as at_least_one_matches
FROM document d
LEFT JOIN user_document ud ON d.id = ud.document_id;
这应该通过,进行左连接,如果 all 匹配,return true,如果 one 匹配,则 false不匹配。如果至少有一个匹配,则第二个 return 为真。
如果你想拍
将连续剧聚合到一个数组中并与所需连续剧的数组进行比较:
SELECT ARRAY(SELECT d.serial
FROM user_document ud
JOIN document d ON d.id = ud.document_id
JOIN "user" u ON u.id = ud.user_id
WHERE u.matricule = '123') @> ARRAY['#1', '#2', '#3']::varchar[];
请注意,我必须在查询中为 user
引用 table 名称,因为它是 PostgreSQL 中的 reserved key word 和 SQL标准。
另一种方法是计算与列表匹配的不同连续出版物的数量,并检查计数是否与列表的长度相匹配:
SELECT count(DISTINCT d.serial) = 3
FROM user_document ud
JOIN document d ON d.id= ud.document_id
JOIN "user" u ON u.id = ud.user_id
WHERE u.matricule='123' AND d.serial IN ('#1','#2','#3');
此版本也适用于不支持数组的数据库(例如MySQL),如果有大量与用户相关的文档,效率可能会更高。
我有一个由 3 tables
组成的简单数据库模式用户
编号
名字
预科
文档
编号
连续剧
User_Document(加入table)
user_id
document_id
我想检查连接中是否存在列表(Document.serial 的列表)的所有项目 table(User_Document) 然后 return 真 如果至少一个不存在,它应该 return false
有我当前的查询
SELECT CASE WHEN EXISTS (
SELECT *
FROM user_document ud
INNER JOIN document d ON d.id= ud.document_id
INNER JOIN user u ON u.id = ud.user_id
where u.matricule='123'
and d.serial in ('#1' ,'#2' , '#3')
)
THEN TRUE
ELSE FALSE
END
这不起作用,因为它 return 始终为真,即使列表中的单个项目不存在于联接中 table
我在 PostgreSQL 下
非常感谢
SELECT
D.*,
(CASE WHEN (SELECT 1 FROM USER_DOCUMENT
WHERE D.ID = UD.DOCUMENT_ID LIMIT 1) = 1 THEN TRUE ELSE FALSE END)
FROM DOCUMENT D
试试这个:
SELECT bool_and(ud.document_id is not null) as all_match,
bool_or(ud.documnet_id is not null) as at_least_one_matches
FROM document d
LEFT JOIN user_document ud ON d.id = ud.document_id;
这应该通过,进行左连接,如果 all 匹配,return true,如果 one 匹配,则 false不匹配。如果至少有一个匹配,则第二个 return 为真。
如果你想拍
将连续剧聚合到一个数组中并与所需连续剧的数组进行比较:
SELECT ARRAY(SELECT d.serial
FROM user_document ud
JOIN document d ON d.id = ud.document_id
JOIN "user" u ON u.id = ud.user_id
WHERE u.matricule = '123') @> ARRAY['#1', '#2', '#3']::varchar[];
请注意,我必须在查询中为 user
引用 table 名称,因为它是 PostgreSQL 中的 reserved key word 和 SQL标准。
另一种方法是计算与列表匹配的不同连续出版物的数量,并检查计数是否与列表的长度相匹配:
SELECT count(DISTINCT d.serial) = 3
FROM user_document ud
JOIN document d ON d.id= ud.document_id
JOIN "user" u ON u.id = ud.user_id
WHERE u.matricule='123' AND d.serial IN ('#1','#2','#3');
此版本也适用于不支持数组的数据库(例如MySQL),如果有大量与用户相关的文档,效率可能会更高。