当前位置: 首页 > 面试题库 >

内联接和左/右外联接的问题

卫建义
2023-03-14
问题内容

我有三个表:

  • 命令

    • OrderId,int PK
    • CustomerId,与客户之间为int FK,允许为NULL
  • 顾客

    • CustomerId,int PK
    • CompanyId,将FK转换为Company,不允许为NULL
  • 公司介绍

    • CompanyId,int PK
    • 名称nvarchar(50)

我想选择所有订单,无论是否有客户,如果有客户,也要选择客户的公司名称。

如果我使用此查询…

SELECT Orders.OrderId, Customers.CustomerId, Companies.Name
FROM   Orders
       LEFT OUTER JOIN Customers
           ON Orders.CustomerId = Customers.CustomerId
       INNER JOIN Companies
           OM Customers.CompanyId = Companies.CompanyId

…它只会返回有客户的订单。如果我替换INNER JOINLEFT OUTER JOIN

SELECT Orders.OrderId, Customers.CustomerId, Companies.Name
FROM   Orders
       LEFT OUTER JOIN Customers
           ON Orders.CustomerId = Customers.CustomerId
       LEFT OUTER JOIN Companies
           OM Customers.CompanyId = Companies.CompanyId

......它的工作原理,但我不明白为什么,因为之间的关系,这是必要的Customers,并Companies要求:客户 必须 有一个公司。

一种可行的替代方法似乎是:

SELECT Orders.OrderId, Customers.CustomerId, Companies.Name
FROM   Companies
       INNER JOIN Customers
           ON Companies.CompanyId = Customers.CompanyId
       RIGHT OUTER JOIN Orders
           OM Customers.CustomerId Orders.CustomerId

该查询具有我期望的内部和外部联接的数量,但问题是对我来说很难阅读,因为我将查询作为 订单
的查询记入其中,订单是选择的“根”,而不是选择的“根”公司。另外RIGHT OUTER JOIN,我的用法也不是很熟悉。

最后一个查询是设计器为SQL Server Reporting
Services报表生成的查询的一小部分。我正在尝试在没有设计人员界面的情况下手动编写查询,因为它非常拥挤,并且在进行许多更改并且将来还会有更多更改之后,我在维护查询方面遇到了问题。因此,我想以某种方式为查询提供可读的结构。

问题:

  1. 为什么查询1不能按我预期的方式工作?
  2. 尽管(或因为?)查询2使用了两个LEFT OTHER JOINS,但它是正确的解决方案吗?
  3. 查询3是正确的解决方案吗?
  4. 有没有更好的方法来编写查询?
  5. 是否存在一些一般的经验法则和实践,以及如何以一种易于阅读的方式编写具有大量外部和内部联接的查询?

问题答案:

语义上,联接按在from子句中出现的顺序进行处理。(由于SQL优化,它们可能实际上未按此顺序执行,但是该顺序对于定义结果集很重要。)

因此,当您这样做时:

from orders left outer join customers inner join companies

on为此,我省去了那些会分散注意力的条款。)

SQL解释为:

from (orders left outer join customers) inner join companies

您正在执行inner join,因此值必须同时出现在两侧。在您的情况下,这会取消的效果left outer join

你要:

from orders left outer join (customers inner join companies)

这里有一些解决方案。

我的首选解决方案是left outer join用于所有联接。实际上,出于可读性和可维护性,我编写的几乎每个查询都将仅是查询表left outer join[inner] join连接表。如果可以以一致的形式编写查询,则必须解析查询以了解联接的语义似乎是不必要的工作。

另一种解决方案是使用括号:

from orders left outer join (customers inner join companies)

另一个解决方案是子查询:

from orders left outer join (select . . . from customers inner join companies) cc


 类似资料:
  • 问题内容: 假设我们有下表t1和t2: 我们希望找到以下结果: 这基本上是右连接与左连接的并集。以下代码有效,但感觉很笨拙: 有没有更好的方法来实现这一目标? 问题答案:

  • 问题内容: 我们有下面的查询。使用LEFT OUTER联接需要9秒钟才能执行。将LEFT OUTER更改为LEFT INNER可以将执行时间减少到2秒,并且返回 相同 数量的行。由于正在处理dbo.Accepts表中相同数量的行,而不论联接类型如何,为什么外层要花3倍的时间? 问题答案: 返回相同行数的事实是事后事实,查询优化器无法预先知道Accepts中的每一行在Marker中都有匹配的行,可以

  • 问题内容: 我知道SQL Server中的联接。 例如。有两个表Table1,Table2。 它们的表结构如下。 表1的数据如下: 表2数据如下: 如果我执行下面提到的两个SQL语句,则两个输出将是相同的 请在上述SQL语句中说明左右联接之间的区别。 问题答案: Select * from Table1 left join Table2 … 和 确实是完全可以互换的。但是,请尝试(或同一对)进行区

  • 问题内容: 我的查询有问题,该查询显示商店列表以及与之关联的产品数量。我已经玩了很长时间的左联接等,但无济于事。这些表具有以下结构: 商店含有表列:, 产品含表列:,,, 查询如下: 我没有去买有0件商品的商店。请问我该如何实现? 基础数据库是MySQL。 谢谢!马耳他 问题答案: 您需要在左侧购物,因为右侧可能没有数据,在本例中为PRODUCT。 不仅如此,您还需要WHERE条件作为LEFT-J

  • 问题内容: 这个问题已经在这里有了答案 : SQL中左右联结与左右联结之间的区别[重复] (4个答案) 6年前关闭。 我看到过称为LEFT OUTER JOIN或RIGHT OUTER JOIN的联接。在某些地方,我见过LEFT JOIN或RIGHT JOIN。我对此感到困惑。 我两天前发布了一个问题,但我无法理解解决方案提供的链接。 这些连接类型是否相同,或者两者之间有区别? 问题答案: 两者之

  • 问题内容: 我有一个网站,用户可以在其中查看电影列表,并为其创建评论。 用户应该能够看到所有电影的列表。此外,如果他们查看了电影,则他们应该能够看到他们给它的评分。如果不是,则仅显示没有得分的电影。 他们根本不在乎其他用户提供的分数。 考虑以下 我本质上想要的是 考虑以下内容: 两个测试都应打印完全相同的输出,但是,只有原始版本会吐出正确的结果表: orm会返回这个 任何试图加入其余主题的尝试,那