我有一个由3个表组成的简单数据库模式
用户
ID
命名
matricule
文档
ID
序列
User_Document (加入表)
USER_ID
document_id
我想检查连接表(User_Document)中是否存在列表的所有项目(Document.serial列表),然后返回true 如果至少有一个不存在,则应返回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
这不起作用,因为即使连接表中不存在单个列表项,它也会一直返回
我在PostgreSQL下
非常感谢
答案 0 :(得分:2)
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
答案 1 :(得分:2)
试试这个:
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 匹配则返回true,如果一个不匹配则返回false。如果至少有一个匹配,则第二个返回true。
如果你想笑
答案 2 :(得分:1)
在数组中聚合连续符并与所需连续符的数组进行比较:
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
的表名,因为它是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),如果有大量与用户相关的文档,则可能更有效。