带有子查询排除的 SQL 选择字段
Posted
技术标签:
【中文标题】带有子查询排除的 SQL 选择字段【英文标题】:SQL selecting field with subquery exclusion 【发布时间】:2015-03-23 18:03:15 【问题描述】:问题的标题可能不是最佳的。
我想要实现的是从尚未删除站点的表site
中检索company_id
。但是,company
有多个站点。我不想选择拥有一个或多个未删除网站的公司。
SELECT DISTINCT(company_id) FROM site WHERE _isDeleted = 1;
提供已删除网站的公司(8000 多个结果)。
但是当我尝试时:
SELECT DISTINCT(company_id) FROM site WHERE _isDeleted = 1
AND company_id NOT IN (SELECT company_id FROM site WHERE _isDeleted = 0);
它给了我 0 个结果。为什么?
那里的性能没有问题,因为它将是一次运行的策略查询。
【问题讨论】:
company_id 是否有可能为空值?因为这会导致使用“Not In”语句出现问题,而需要“Not Exists”。我想另一个问题是您是否确保您的子查询在单独运行时,其结果与您的主要查询的 company_id 结果没有区别。 我试过SELECT DISTINCT(company_id) FROM site WHERE _isDeleted = 1 AND NOT _isDeleted = 0;
,它显示一个空结果。我不知道这是否是我正在寻找的结果,但你对空值是正确的
要确认您的子查询中的公司 ID 为空值,我将运行以下命令:SELECT company_id FROM site WHERE _isDeleted = 0 and company_id is null
第一个查询告诉我你有 8000 多家公司至少有一个被删除的网站。第二个告诉我,在这 8000 多家公司中,他们都至少有一个没有被删除的网站。也许 0 是有效的回报?
【参考方案1】:
我倾向于非常不喜欢成语NOT IN (<subquery>)
的大多数用法。对于这种特殊需求,我会考虑这样的查询:
SELECT company_id
FROM site
GROUP BY company_id
HAVING COUNT(*) != COUNT(NULLIF(_isDeleted, 0))
这适用于_isDeleted
的任何值,NULL
等效于0
,所有其他值等效于1
。我还发现它的含义比原始查询的含义更清晰,如果您关心性能,那么它的性能可能会更好。
【讨论】:
【参考方案2】:根据您的要求,您需要从表站点中所有未删除站点的公司,您可以轻松执行以下操作
select distinct company_id from site where _isdeleted=0 and company_id is not null
要删除没有网站的公司,您可以使用
select distinct company_id from site p
where not exists(select 1 from site x
where x.company_id=p.company_id and x._isdeleted=1)
and p._isdeleted=0
希望对你有帮助
【讨论】:
以上是关于带有子查询排除的 SQL 选择字段的主要内容,如果未能解决你的问题,请参考以下文章