【问题标题】:SQL - check if a value in a list does not exist in table and return boolean accordinglySQL - 检查列表中的值是否在表中不存在并相应地返回布尔值
【发布时间】:2018-02-08 03:03:25
【问题描述】:

我有一个由 3 个表组成的简单数据库架构

用户
身份证
名称
矩阵

文档
身份证
串行

User_Document(连接表)
用户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

这不起作用,因为即使连接表中不存在列表的单个项目,它也会始终返回 true

我在PostgreSQL下

非常感谢

【问题讨论】:

  • I want to check if all items of a document serial list exists in... 你的意思是:如果一个元素不存在(但其他元素存在),它应该返回 False?请改写...
  • @Wildplasser 。对,就是那样 。谢谢

标签: sql postgresql relational-division


【解决方案1】:
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

【讨论】:

  • 我需要从现有文档序列列表中比较不是文档中的所有条目。谢谢
【解决方案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,如果 one 不匹配则返回 false。如果至少有一个匹配,则第二个返回 true。

如果你想买

【讨论】:

  • 这几乎是我想要的结果,除了我想过滤定义的文档ID列表而不是整个表格(如我的示例所示)非常感谢
  • 然后添加 where 子句。聚合作用于 where 子句未排除的行。
【解决方案3】:

在一个数组中聚合序列并与所需序列的数组进行比较:

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 和 SQL 标准中是 reserved key word

另一种方法是计算与列表匹配的不同连续剧,并检查计数是否与列表长度匹配:

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),如果有大量与用户相关的文档,效率可能会更高。

【讨论】:

  • 谢谢,但我得到一个 " 运算符不存在:字符变化 [] @> text[] 。没有运算符匹配给定的名称和参数类型。您可能需要添加显式类型强制转换。" :(
  • 已将演员表添加到varchar[],请重试。您能否使用架构的完整 DDL 更新您的问题,包括每列的类型?
猜你喜欢
  • 2012-06-18
  • 1970-01-01
  • 1970-01-01
  • 2018-11-14
  • 2021-11-01
  • 2023-03-28
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
相关资源
最近更新 更多