【问题标题】:Suggest optimized query using 4 tables ( RIGHT JOIN v/s INNER JOIN & HAVING )建议使用 4 个表优化查询(RIGHT JOIN vs INNER JOIN & HAVING)
【发布时间】:2016-02-13 20:14:03
【问题描述】:

我有以下表结构

  • table_country ==> country_id (PK) |国家 |状态
  • table_department ==> 部门 ID (PK) |部门 | country_id (FK)
  • table_province ==> Province_id (PK) |省| department_id (FK)
  • table_district ==> District_id (PK) |区 | Province_id (FK)

注意:所有的表引擎都是innoDB

一个国家可以有多个部门,一个部门可以有多个省,一个省可以有多个区。现在我只需要搜索那些至少有一个地区的国家

我编写了以下 2 个 SQL 查询,就我而言,两个查询返回相同的结果....请描述这些查询之间的区别

使用RIGHT JOIN

SELECT c.country_id as id, c.country as name 
FROM table_country c 
RIGHT JOIN table_department d ON d.country_id=c.country_id 
RIGHT JOIN  table_province p ON p.department_id=d.department_id 
RIGHT JOIN table_district ds ON ds.province_id=p.province_id 
WHERE c.status='Active' GROUP BY (c.country_id)

使用INNER JOINHAVING 子句:

SELECT COUNT(ds.district), c.country_id as id, c.country as name 
FROM table_country c 
INNER JOIN table_department d ON d.country_id = c.country_id 
INNER JOIN table_province p ON p.department_id = d.department_id 
INNER JOIN table_district ds ON ds.province_id = p.province_id 
WHERE c.status='Active' 
GROUP BY (c.country_id)  
HAVING  COUNT(ds.district)>0

请告诉我这两个查询在结果中的不同之处以及我必须使用哪个查询还是必须使用不同的查询?

提前致谢

【问题讨论】:

  • 第二个查询似乎缺少GROUP BY country_id,country。 INNER JOIN 使HAVING 变得多余。
  • @pascal AFAIK 在内部联接中,我们只会在右联接或左联接也为您提供空记录的情况下获得匹配记录。
  • @pascal 一起使用 INNER JOIN 和 HAVING 会发生什么冗余,建议一些例子
  • 例如考虑到第一个INNER JOIN,它只会返回包含(至少)一个部门的国家,所以部门不为空。对于其他joins,递归也是如此,因此国家不为空。 LEFT JOIN(或CROSS JOIN)可以返回没有匹配部门的国家,留下一个空部门。
  • 第一个查询的 RIGHT JOIN 将允许没有匹配 contry 的部门。但这被c.status='Active' 谓词所抵消,该谓词过滤掉(至少)null contry。

标签: sql mysql join


【解决方案1】:

我建议使用您的 2 个查询中的第二个(带有内部联接),但没有 HAVING 子句,因为它不是必需的,因为内部联接要求最终结果中的任何行必须在区域表中有一行.

您的第一个查询使用更奇特的 RIGHT OUTER JOINS 系列,最终会产生相同的结果 - 但由于它们是外部连接,因此效率可能较低。表示您的第一个查询的另一种方法是像这样反转表序列:

SELECT
      c.country_id AS id
    , c.country AS name
    , COUNT(ds.district)
FROM table_district ds
      INNER JOIN table_province p ON ds.province_id = p.province_id
      INNER JOIN table_department d ON p.department_id = d.department_id
      INNER JOIN table_country c ON d.country_id = c.country_id
WHERE c.status='Active'
GROUP BY
      c.country_id
    , c.country

希望当像这样倒置时,很明显,除非区表中有一行,否则不存在任何结果行。

【讨论】:

    猜你喜欢
    • 2018-01-27
    • 2015-08-25
    • 2011-08-18
    • 2012-02-02
    • 1970-01-01
    • 2014-03-13
    • 1970-01-01
    • 1970-01-01
    • 2014-11-17
    相关资源
    最近更新 更多