我有两张桌子:
customer_name)
我希望找到所有的客户,例如,没有租金合同。
我可以这样做:
SELECT contragent_name
FROM contragents
WHERE contragent_id NOT IN (SELECT contragent_id
FROM documents
WHERE document_name = 'Rent contract');有人能建议在没有第二次选择的情况下如何做吗?
发布于 2021-09-11 08:24:15
左联接是另一种选择:
SELECT c.contragent_name
FROM contragents AS c
LEFT JOIN documents d.
ON c.contragent_id = d.contragent_id
AND document_name = 'Rent contract'
WHERE d.contragent_id IS NULL;但通常情况下,不存在条件是最有效的方法(如果性能有差异-这在很大程度上取决于实际使用的DBMS )。
SELECT c.contragent_name
FROM contragents c
WHERE NOT EXISTS (SELECT *
FROM documents d
WHERE d.document_name = 'Rent contract'
AND d.contragent_id = c.contragent_id);发布于 2021-09-11 08:22:39
你可以用左反连接来重新表述你的要求:
SELECT c.contragent_name
FROM contragents c
LEFT JOIN documents d
ON d.contragent_id = c.contragent_id AND
d.document_name = 'Rent contract'
WHERE
d.contragent_id IS NULL;但是,如果要将上述解释计划和性能与子查询方法进行比较,您可能会发现类似的情况。实际上,通过添加以下索引,可以轻松地执行当前的方法:
CREATE INDEX idx ON documents (contragent_id, document_name);此索引应允许快速查找contragents表中的任何记录。
发布于 2021-09-11 08:21:28
在左表键为null的情况下,使用左联接和筛选器(但仍然需要嵌套查询才能获得带有名称Rent契约的文档子集):
SELECT c.contragent_name
FROM contragents AS c
LEFT JOIN (
SELECT contragent_id FROM documents WHERE document_name = 'Rent contract'
) AS d ON c.id = d.contragent_id
WHERE d.id IS NULL;这有时被称为失败的连接。对于受挫的连接和未选择的连接的性能比较取决于不同的因素,如使用中的数据库系统、记录的数量、有时查询优化器可能使用的数据库统计数据/趋势。
https://stackoverflow.com/questions/69141218
复制相似问题