带有子查询排除的 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 选择字段的主要内容,如果未能解决你的问题,请参考以下文章

如何将带有子选择的 SQL 查询转换为 MDX 查询?

转置带有子选择和计数的 sql 查询

带有子查询的休眠选择查询?

带有(来自)别名的 SQL 子查询

SQL 从带有子查询的多个表中选择数据(包括来自内部连接的数据)错误:1242

SQL高级子选择查询