【问题标题】:Which JOIN type in multiple joins多个连接中的哪个 JOIN 类型
【发布时间】:2015-06-08 10:32:19
【问题描述】:

我有 4 个要加入的表。

  1. Customers
  2. Traffic
  3. Average
  4. Live

我想将这些表的连接数据插入到“详细信息”表中。 表之间的关系在这里: 每个 Traffic、Average 和 Live 表都有一个“cid”,它是“Customers”表的主键:

  • Traffic.cid = Customers.id
  • Average.cid = Customers.id
  • Live.cid = Customers.id

我写的查询在这里:

INSERT INTO Details
(
cid, Customer_Name, Router_Name,
Traffic_Received,
Average_Received,
Live_Received,
date
)     
(
SELECT Customers.id AS cid, Customers.name AS Customer_Name, Traffic.Router_Name,
Traffic.Received, 
Average.Received,
Live.Received, 
Traffic.date
FROM Customers
INNER JOIN Traffic ON Customers.id=Traffic.cid
INNER JOIN Average ON Customers.id=Average.cid
INNER JOIN Live ON Customers.id=Live.cid
WHERE Traffic.date='2015-06-08'
)

但结果会有重复的行。我将JOIN 更改为LEFT JOINRIGHT JOIN。但结果没有改变。 我应该怎么做才能在Details 表中没有重复的行?

【问题讨论】:

  • 4个表中的所有数据都是唯一的。 distinct 没有任何变化。
  • @BayanB 。 . .你说:“但结果会有重复的行。”。有没有重复?使用示例数据和所需结果编辑您的问题。更好的是,使用 SQL Fiddle。
  • @BayanB,这不能保证......
  • 请注意,外连接通常返回与内连接相同或更多的行数!

标签: mysql sql join left-join right-join


【解决方案1】:

使用LEFT JOIN,即使没有与Customers.id 对应的记录,您也将加入表(例如Traffic),在这种情况下,您将获得null 值此表中没有匹配记录的列。

使用RIGHT JOIN,即使Customers 中没有对应的记录,您也会从连接表中获取每条记录。

但是,JOIN 的类型不是这里的问题。如果您在结果中获得重复记录,则这意味着您要加入的表中有多个匹配记录。例如,Traffic 中可能有多个记录具有相同的cid。使用 SELECT DISTINCT 删除重复项,或者如果您对这些重复项的聚合感兴趣,请使用聚合函数,例如 count()sum()GROUP BY 子句,例如GROUP BY Traffic.cid.

如果您仍然有重复,请检查以确保它们确实是重复的 - 我建议一列或多列实际上是不同的。

【讨论】:

    【解决方案2】:

    你可以试试这个

            INSERT INTO Details
        (
            cid, Customer_Name, Router_Name,
            Traffic_Received,
            Average_Received,
            Live_Received,
            date
        )     
        (
        SELECT Customers.id AS cid, 
            Customers.name AS Customer_Name, 
            Traffic.Router_Name,
            Traffic.Received, 
            Average.Received,
            Live.Received, 
            Traffic.date
        FROM Customers
        INNER JOIN Traffic ON Customers.id=Traffic.cid
        INNER JOIN Average ON Customers.id=Average.cid
        INNER JOIN Live ON Customers.id=Live.cid
        WHERE Traffic.date='2015-06-08'
        GROUP BY
            cid,
            Customer_Name,
            Traffic.Router_Name,
            Traffic.Received, 
            Average.Received,
            Live.Received, 
            Traffic.date
        )
    

    【讨论】:

    • 为什么不节省大量的输入,而改为执行 SELECT DISTINCT?
    【解决方案3】:
    SELECT Customers.id AS cid, Customers.name AS Customer_Name, Traffic.Router_Name,
    Traffic.Received, 
    Average.Received,
    Live.Received, 
    Traffic.date
    FROM Customers
    LEFT JOIN Traffic ON Customers.id=Traffic.cid
    LEFT JOIN Average ON Traffic.cid=Average.cid
    LEFT JOIN Live ON Average.cid=Live.cid
    WHERE Traffic.date='2015-06-08'
    

    【讨论】:

    • 结果没有区别
    • 在这种情况下,您的表格在该日期必须为每位客户提供多个条目。选择一个客户,看看他们在您的日期的每个表格中都有哪些数据。
    • 详细信息表每天都会保存这些数据,对于每个客户,每天只有一个条目。例如,对于 2015 年 6 月 8 日,3 个表(Traffic、Live 和 Average)中的每一个都有每个客户的一条记录。
    猜你喜欢
    • 2020-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多