【问题标题】:Executing an equijoin as a natural join将等值连接作为自然连接执行
【发布时间】:2019-10-14 22:06:24
【问题描述】:

我是 SQL 新手。

我希望执行一个涉及两个表作为等值连接和自然连接的查询,我在其中计算客户按城市下订单的实例。如果客户 ID 出现在 ordertable 关系中,我假设客户已下订单。

我正在尝试在一个查询中组合 equijoin、COUNT() 和 GROUP BY,然后在另一个查询中使用 NATURAL JOIN 重复相同的查询。

请参阅下面的代码了解我的尝试及其结果。

以下等值连接:

SELECT customer.city, COUNT(*) AS total FROM customer, ordertable
WHERE customer.cust_id = ordertable.cust_id
GROUP BY customer.city
ORDER BY customer.city ASC
;

产量

  1. 城市 |计数
  2. 顺丰 | 1
  3. SLC | 7
  4. 图森 | 2

但是:

SELECT city, COUNT(*) AS total
FROM customer
NATURAL JOIN orderline
GROUP BY customer.city, city
ORDER BY customer.city ASC
;

产量

  1. 城市|总计
  2. 洛杉矶 | 34
  3. SF |17
  4. SLC | 170
  5. 图森 | 34

我相信第一组结果是正确的,但我不明白为什么这两种不同的方法会产生不同的结果。

【问题讨论】:

  • 我会避免这两种类型并使用适当的JOIN ON 子句。第一种样式不再是“标准”,第二种不显示 JOIN 使用了哪些特定列。
  • 请在代码问题中给出minimal reproducible example--剪切&粘贴&可运行代码;具有期望和实际输出(包括逐字错误消息)的示例输入(作为初始化代码);标签和版本;明确的规范和解释。这包括您可以提供的最少代码,即您显示的代码可以通过您显示的代码扩展为不可以。 (调试基础。)对于包含 DBMS/产品和 DDL 的 SQL,其中包括约束和索引以及表格格式的初始化。

标签: sql join group-by count


【解决方案1】:

您正在比较苹果和橙子并说明为什么应该避免使用natural joins。干脆不要使用它们。

你应该学习的查询是:

SELECT c.city, COUNT(*) AS total
FROM customer c JOIN
     ordertable ot
     ON c.cust_id = ot.cust_id
GROUP BY c.city
ORDER BY c.city ASC;

您的第二个查询连接到一个不同orderline,它没有 cust_id。因此,“自然连接”正在生成笛卡尔积。

注意以下几点:

  • joinfrom 子句中是显式的。
  • join 条件在查询中是明确的。不用猜了。
  • 表别名使查询更易于编写和阅读。

我认为natural join 是可憎的,因为它没有考虑正确声明的外键关系。相反,它只是依赖列的命名约定来匹配表。

并且,不会检测到应该导致错误的问题 - 例如缺少 join 键。

【讨论】:

  • 感谢您指出我使用了错误的关系这一事实。当没有检测到cust_id 列时没有抛出错误,这很烦人。我再也不会碰NATURAL JOIN了。
猜你喜欢
  • 2018-11-30
  • 2011-12-13
  • 1970-01-01
  • 2014-11-14
  • 2016-07-10
  • 2016-10-29
  • 1970-01-01
  • 2012-01-31
相关资源
最近更新 更多