gpt4 book ai didi

sql - 在什么情况下这两个 SQL 查询会给出不同的结果?

转载 作者:行者123 更新时间:2023-12-02 07:27:27 25 4
gpt4 key购买 nike

免责声明:我正在通过在线教程帮助一个人学习 SQL。所以你可以把它当作一道作业题。

我们在这里处理 3 个 SQL Server 表:

  • 船舶(名称、等级)
  • Classes - 船舶的不同级别(class)
  • 结果——那艘船发生了什么事(船,结果)

现在数据库的布局中有几件疯狂的事情,最大的一件是 Outcomes 表中的船只可能不会出现在 Ships 表中它们的命名方式与 Class 中的类相同。

重点是获取每个级别的沉船数量。我已帮助学生获得以下 SQL:

Select 
dbo.Classes.[class], Count(dbo.Outcomes.ship) as [count]
from
dbo.Classes
left join
dbo.Ships on dbo.Ships.[class] = dbo.Classes.[class]
left join
dbo.Outcomes on (dbo.Outcomes.ship = dbo.Classes.[class] or
dbo.Outcomes.ship = dbo.Ships.name)
and dbo.Outcomes.result = 'sunk'
Group by
dbo.Classes.[class]

但是,显然,这是不正确的解决方案,因为它有时会返回不正确的结果。在网上,我设法找到了本教程的以下解决方案:

select 
classes.class, count(T.ship)
from
classes
left join
(select
ship, class
from
outcomes
left join
ships on ship = name
where
result = 'sunk'
union
select
ship, class
from
outcomes
left join
classes on ship = class
where
result = 'sunk') as T on classes.class = T.class
group by
classes.class

但我无法理解在什么情况下结果会有所不同。使用两个不同连接路径的 Union 操作是否与连接条件下的 OR 具有完全相同的功能?

附言本教程中的这个特定问题实际上在 1-5 的难度等级上标记为 2。所以我觉得自己很傻。

最佳答案

有了这个数据集:

with Ships as (
select * from (values
('HMS Prince of Wales','King George V')
,('King George V','King George V')
)Ships(name,class)
),
Classes as (
select * from (values
('King George V')
)Classes(class)
),
Outcomes as (
select * from (values
('HMS Prince of Wales','sunk')
,('King George V','sunk')
)Outcomes(ship,result)
)

您提供的两个查询分别产生:

class         count
------------- -----------
King George V 3

class
------------- -----------
King George V 2

差异的原因是 UNION 是一个消除重复项的集合运算符(与 UNION ALL 不同),而 OR 运算符则不是吨。我们可以通过将第二个查询中的 UNION 替换为 UNION ALL 来测试这一点,现在会产生:

class         
------------- -----------
King George V 3

就像您第一个提出的解决方案一样。

关于sql - 在什么情况下这两个 SQL 查询会给出不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26452150/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com