【问题标题】:MySQL FULL JOIN?MySQL 完全连接?
【发布时间】:2011-12-20 04:33:09
【问题描述】:

以下是我的查询,我希望得到如下所示的结果。我怎样才能在 mysql 中做到这一点?

SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
FULL JOIN Orders
ON Persons.P_Id=Orders.P_Id
ORDER BY Persons.LastName

结果集需要如下所示:

LastName      FirstName     OrderNo
Hansen        Ola          22456
Hansen        Ola          24562
Pettersen     Kari         77895
Pettersen     Kari         44678
Svendson      Tove   
                           34764

【问题讨论】:

  • 您可以投票支持该功能的实现at MySql

标签: mysql


【解决方案1】:

MySQL 不支持 FULL OUTER JOIN。

因此,如果您想在 MySQL 上模拟完全连接,请查看 here

通常建议的解决方法如下所示:

SELECT  t_13.value AS val13, t_17.value AS val17
FROM    t_13
LEFT JOIN
        t_17
ON      t_13.value = t_17.value
UNION ALL
SELECT  t_13.value AS val13, t_17.value AS val17
FROM    t_13
RIGHT JOIN
        t_17
ON      t_13.value = t_17.value
WHERE   t_13.value IS NULL
ORDER BY
        COALESCE(val13, val17)
LIMIT 30

【讨论】:

  • 如何按指定的一列对所有注册表进行排序?
【解决方案2】:

完整的mysql FULL [OUTER] JOIN有几种方法。

  1. UNION 一个左连接和右连接。 UNION 将通过执行 ORDER BY 操作来删除重复项。 因此,根据您的数据,它可能性能不佳。

     SELECT * FROM A 
       LEFT JOIN B ON A.key = B.key 
    
     UNION 
    
     SELECT * FROM A 
       RIGHT JOIN B ON A.key = B.key
    
  2. UNION ALL 左连接和右 EXCLUDING 连接(即图中右下角的图)。 UNION ALL 不会删除重复项。有时这可能是您想要的行为。您还希望使用 RIGHT EXCLUDING 来避免重复选择 A 和选择 B 中的常见记录 - 即左连接已经包含选择 B 中的常见记录,我们不要再使用右连接重复。

     SELECT * FROM A 
       LEFT JOIN B ON A.key = B.key 
    
     UNION ALL
    
     SELECT * FROM A 
       RIGHT JOIN B ON A.key = B.key
       WHERE A.key IS NULL
    

【讨论】:

    【解决方案3】:
    SELECT  p.LastName, p.FirstName, o.OrderNo
    FROM    persons AS p
    LEFT JOIN
            orders AS o
    ON      o.orderNo = p.p_id
    UNION ALL
    SELECT  NULL, NULL, orderNo
    FROM    orders
    WHERE   orderNo NOT IN
            (
            SELECT  p_id
            FROM    persons
            )
    

    【讨论】:

    • 如何按指定的一列对所有注册表进行排序?
    • @Luitame:这应该是另一个问题,而不是评论。
    【解决方案4】:

    试试这个:

    (SELECT p.LastName, p.FirstName, o.OrderNo
     FROM   Persons p
       LEFT JOIN Orders o
       ON o.OrderNo = p.P_id
    )
    UNION
    (SELECT p.LastName, p.FirstName, o.OrderNo
     FROM   Persons p
       RIGHT JOIN Orders o
       ON o.OrderNo = p.P_id
    );
    
    +----------+-----------+---------+
    | LastName | FirstName | OrderNo |
    +----------+-----------+---------+
    | Singh    | Shashi    |       1 |
    | Yadav    | Sunil     |    NULL |
    | Singh    | Satya     |    NULL |
    | Jain     | Ankit     |    NULL |
    | NULL     | NULL      |      11 |
    | NULL     | NULL      |      12 |
    | NULL     | NULL      |      13 |
    +----------+-----------+---------+
    

    【讨论】:

    • 重要的是要注意使用UNION,而不是UNION ALL
    • 这里使用了UNION,它将删除重复项并执行排序操作。如果您想要更高性能的查询或想要保留重复项,请使用 UNION ALL。
    【解决方案5】:

    嗯,将 LEFT 和 RIGHT JOIN 与 UNION 结合可以做到这一点:

    SELECT  p.LastName, p.FirstName, o.OrderNo
    FROM    persons AS p
    LEFT JOIN
            orders AS o
    ON      p.P_Id = Orders.P_Id
    UNION ALL
    SELECT  p.LastName, p.FirstName, o.OrderNo
    FROM    persons AS p 
    RIGHT JOIN
            orders AS o
    ON      p.P_Id = Orders.P_Id
    WHERE   p.P_Id IS NULL
    

    【讨论】:

      【解决方案6】:

      完全加入 mysql :(left union right) or (right unoin left)

       SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
          FROM Persons
          left JOIN Orders
          ON Persons.P_Id=Orders.P_Id
          ORDER BY Persons.LastName
      
          Union
      
          SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
          FROM Persons
          Right JOIN Orders
          ON Persons.P_Id=Orders.P_Id
          ORDER BY Persons.LastName
      

      【讨论】:

      • 这里使用了UNION,它将删除重复项并执行排序操作。如果您想要更高性能的查询或想要保留重复项,请使用 UNION ALL
      【解决方案7】:

      这里每个人都是正确的,但是两次编写相同的查询并不是一种好的编程方式...... 所以我有另一种方法可以在 mysql 中进行完全连接,如下所示

      SELECT
       user_id , user_name, user_department 
      FROM 
       (SELECT 
           user_id  , user_name , NULL as user_department 
        FROM
         tb_users 
       UNION 
         SELECT 
           user_id ,NULL as user_name , user_department
         FROM 
            tb_departments
       ) as t group by user_id
      

      【讨论】:

        猜你喜欢
        • 2016-09-13
        • 2013-03-11
        • 2021-10-12
        • 1970-01-01
        • 1970-01-01
        • 2017-06-09
        • 2011-12-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多