Sql 将not in子句更改为内部联接
如何将以下查询转换为内部联接并避免使用distinct来优化性能Sql 将not in子句更改为内部联接,sql,sql-server,Sql,Sql Server,如何将以下查询转换为内部联接并避免使用distinct来优化性能 select distinct(GroupId) from BatchQuotaIndividualQuotas where BatchQuotaCommonSettingsID = 58 and GroupId not in ( select distinct(groupid) from BatchQuotaIndivid
select distinct(GroupId)
from BatchQuotaIndividualQuotas
where BatchQuotaCommonSettingsID = 58
and
GroupId not in
(
select distinct(groupid)
from BatchQuotaIndividualQuotas
where BatchQuotaCommonSettingsID = 58
and ObjectiveFunctionTotalResultID is null
)
GroupId不是主键。有多行对应于单个GroupId。我想选择ObjectiveFunctionTotalResultID均不为空的GroupId 你能试试这个吗
select GroupId
from BatchQuotaIndividualQuotas
where BatchQuotaCommonSettingsID = 58
and ObjectiveFunctionTotalResultID IS NOT NULL
GROUP BY GroupId
同样的问题,如果我对一些修改后的流程是正确的。它没有通过子查询过滤出ID,而是就地进行过滤。您能试试这个吗
select GroupId
from BatchQuotaIndividualQuotas
where BatchQuotaCommonSettingsID = 58
and ObjectiveFunctionTotalResultID IS NOT NULL
GROUP BY GroupId
同样的问题,如果我对一些修改后的流程是正确的。它不是通过子查询过滤出ID,而是就地过滤。首先,distinct不是一个函数,而是select语句的修饰符。您可以选择字段值的不同组合,而不是不同的单个字段。如果有更多字段,括号实际上会调用语法错误。所以不是
select
distinct(groupid)
但是
其次,你根本不需要内在的区别。in列表中可能存在重复项,dbms可能已经为您对此进行了优化。通过在内部查询中添加distinct yourself,您可以主动阻止优化器完成其工作
第三,如果您想要拥有不同的组ID,那么您仍然需要在外部查询上使用distinct。内部联接不会改变这一点。此外,由于您希望有不匹配的记录,因此内部联接不能起作用。左连接可以做到这一点,但如果我正确解释您的查询,您可以将其编写为:
select distinct
GroupId
from
BatchQuotaIndividualQuotas
where
BatchQuotaCommonSettingsID = 58 and
ObjectiveFunctionTotalResultID is not null
你可以像我在下面所做的那样将其更改为“分组方式”,但效果是一样的。GROUPBY只创建组,还必须删除重复项。Group by主要用于聚合。我不确定内部的工作方式,但理论上分组是一个比较困难的过程,因为数据库需要为这些聚合创建实际的组,而不仅仅是过滤掉重复的组。可能这也会得到优化,因此最终,下面的查询将执行与上面的查询相同的操作
select
GroupId
from
BatchQuotaIndividualQuotas
where
BatchQuotaCommonSettingsID = 58 and
ObjectiveFunctionTotalResultID is not null
group by
GroupId
首先,distinct不是函数,而是select语句的修饰符。您可以选择字段值的不同组合,而不是不同的单个字段。如果有更多字段,括号实际上会调用语法错误。所以不是
select
distinct(groupid)
但是
其次,你根本不需要内在的区别。in列表中可能存在重复项,dbms可能已经为您对此进行了优化。通过在内部查询中添加distinct yourself,您可以主动阻止优化器完成其工作
第三,如果您想要拥有不同的组ID,那么您仍然需要在外部查询上使用distinct。内部联接不会改变这一点。此外,由于您希望有不匹配的记录,因此内部联接不能起作用。左连接可以做到这一点,但如果我正确解释您的查询,您可以将其编写为:
select distinct
GroupId
from
BatchQuotaIndividualQuotas
where
BatchQuotaCommonSettingsID = 58 and
ObjectiveFunctionTotalResultID is not null
你可以像我在下面所做的那样将其更改为“分组方式”,但效果是一样的。GROUPBY只创建组,还必须删除重复项。Group by主要用于聚合。我不确定内部的工作方式,但理论上分组是一个比较困难的过程,因为数据库需要为这些聚合创建实际的组,而不仅仅是过滤掉重复的组。可能这也会得到优化,因此最终,下面的查询将执行与上面的查询相同的操作
select
GroupId
from
BatchQuotaIndividualQuotas
where
BatchQuotaCommonSettingsID = 58 and
ObjectiveFunctionTotalResultID is not null
group by
GroupId
使用左连接,然后将连接结果设置为NULL,可以获得类似的结果 您也可以通过GROUP BY和Have获得相同的结果,尽管我怀疑这种方法会更快
select GroupId
from BatchQuotaIndividualQuotas
where BatchQuotaCommonSettingsID = 58
group by GroupId
having SUM(CASE WHEN ObjectiveFunctionTotalResultID IS NULL THEN 1 ELSE 0 END) = 0
使用左连接,然后将连接结果设置为NULL,可以获得类似的结果 您也可以通过GROUP BY和Have获得相同的结果,尽管我怀疑这种方法会更快
select GroupId
from BatchQuotaIndividualQuotas
where BatchQuotaCommonSettingsID = 58
group by GroupId
having SUM(CASE WHEN ObjectiveFunctionTotalResultID IS NULL THEN 1 ELSE 0 END) = 0
如果从where子句中删除distinct,查询将运行得更快 这里有两种更好的写作方法 countObjectiveFunctionTotalResultID将计数非空值
SELECT GroupId
FROM BatchQuotaIndividualQuotas
WHERE BatchQuotaCommonSettingsID = 58
GROUP BY GroupId
HAVING count(ObjectiveFunctionTotalResultID) = count(*)
或:
除此之外,将包括不同的
SELECT GroupId
FROM BatchQuotaIndividualQuotas
WHERE BatchQuotaCommonSettingsID = 58
EXCEPT
SELECT GroupId
FROM BatchQuotaIndividualQuotas
WHERE BatchQuotaCommonSettingsID = 58
AND ObjectiveFunctionTotalResultID is null
如果从where子句中删除distinct,查询将运行得更快 这里有两种更好的写作方法 countObjectiveFunctionTotalResultID将计数非空值
SELECT GroupId
FROM BatchQuotaIndividualQuotas
WHERE BatchQuotaCommonSettingsID = 58
GROUP BY GroupId
HAVING count(ObjectiveFunctionTotalResultID) = count(*)
或:
除此之外,将包括不同的
SELECT GroupId
FROM BatchQuotaIndividualQuotas
WHERE BatchQuotaCommonSettingsID = 58
EXCEPT
SELECT GroupId
FROM BatchQuotaIndividualQuotas
WHERE BatchQuotaCommonSettingsID = 58
AND ObjectiveFunctionTotalResultID is null
这无法正常工作,因为GroupId不是主键。有多行对应于单个GroupId。我想选择ObjectiveFunctionTotalResultID均不为空的GroupId。这无法正常工作,因为GroupId不是主键。有多行对应于单个GroupId。我想选择ObjectiveFunctionTotalResultID均不为空的GroupId。您的答案不正确,原因与Alex的回答中所述的相同,说明了添加表结构、问题键等信息的重要性:我看看我能做些什么。看看,你可以用
一个左连接,在我的-尽管是-回答查询之前我已经简要地提到过。但是@Dan已经在他的答案中找到了解决方案,所以你可以选择他的答案除了我发布了2个更好的答案,这不是意见的问题,而是性能和可读性的问题。这不是哲学,你的答案不正确,原因与Alex的回答中所述的相同,说明了添加表结构、问题关键等信息的重要性我来看看我能做些什么。看一看,你可以用一个左连接来解决它,我在我的-尽管是-答案查询之前已经简要地提到了。但是@Dan已经在他的答案中找到了解决方案,所以你可以选择他的答案除了我发布了2个更好的答案,这不是意见的问题,而是性能和可读性的问题。这不是哲学