【问题标题】:Two right joins两个右连接
【发布时间】:2016-04-27 04:27:27
【问题描述】:

我正在尝试使用右连接选择 TABLEC 中的所有记录及其在 TABLEA 或 TABLEB 中的等效值。我正在使用 MYSQL 5.5.47。

--表格数据如下

TABLEA          TABLEB      TABLEC  
ID  FNAME       ID  MNAME   ID  LNAME
0   ANOOP       0   N       0   SINGH
1   BIMA        2   SITA    3   RAJ
4   CIMI        4   B       5   KUMAR
6   RAVI        5   A       6   D

--使用下面的查询并尝试选择 TABLEC 中的所有记录及其在 TABLEA 或 TABLEB 中的等效值

 SELECT A.FNAME, B.MNAME, C.LNAME
 FROM TABLEA AS A 
 RIGHT JOIN TABLEB AS B ON A.ID = B.ID 
 RIGHT JOIN TABLEC AS C ON C.ID = B.ID

--我得到以下结果

ANOOP           N       SINGH                   
NULL            NULL    RAJ                 
NULL            A       KUMAR                   
***NULL***      NULL    D

在 MYSQL 5.5.47 中,突出显示的值不会显示为“RAVI”,而是显示为 NULL。我试图修改与 C & A 相关的第二个连接中的 '=' 条件,但仍然没有运气。我在这里做错了什么?如何获得值“RAVI”来代替 NULL?任何建议都会非常有帮助。

【问题讨论】:

  • 添加有问题的预期结果
  • 表 A RIGHT JOIN 表 B 给出“获取表 A 中键与表 B 中匹配的所有记录,并返回表 B 的所有行”。因此,在您的第一个连接语句本身中,Ravi ,其 id 为 6 且其 id 6 不存在于表 B 中,正在被淘汰。我们如何决定需要右连接?
  • 您是否在此处寻找完整的外部联接?还是只保留显示为姓氏的记录?
  • 虽然理论上每个 LEFT JOIN 都有一个逻辑上等价的 RIGHT JOIN,但在实践中 RIGHT JOIN 非常罕见 - 我怀疑部分原因是,像我一样,许多人发现它们违反直觉。跨度>
  • 切换到左连接。大多数人觉得右连接太混乱了。

标签: mysql sql


【解决方案1】:
DROP TABLE IF EXISTS table_a;
DROP TABLE IF EXISTS table_b;
DROP TABLE IF EXISTS table_c;

CREATE TABLE table_a
(id INT NOT NULL PRIMARY KEY
,fname VARCHAR(12) NULL
);

INSERT INTO table_a VALUES
(0,'ANOOP'),
(1,'BIMA'),
(4,'CIMI'),
(6,'RAVI');

CREATE TABLE table_b
(id INT NOT NULL PRIMARY KEY
,mname VARCHAR(12) NULL
);

INSERT INTO table_b VALUES
(0,'N'),
(2,'SITA'),
(4,'B'),
(5,'A');

CREATE TABLE table_c
(id INT NOT NULL PRIMARY KEY
,lname VARCHAR(12) NULL
);

INSERT INTO table_c VALUES
(0,'SINGH'),
(3,'RAJ'),
(5,'KUMAR'),
(6,'D');

 SELECT a.fname
      , b.mname
      , c.lname 
   FROM table_c c 
   LEFT 
   JOIN table_a a  
     ON a.id = c.id 
   LEFT 
   JOIN table_b b 
     ON b.id = c.id;
+-------+-------+-------+
| fname | mname | lname |
+-------+-------+-------+
| ANOOP | N     | SINGH |
| NULL  | NULL  | RAJ   |
| NULL  | A     | KUMAR |
| RAVI  | NULL  | D     |
+-------+-------+-------+
4 rows in set (0.02 sec)

【讨论】:

    【解决方案2】:

    您正在尝试使用右连接选择 TABLEC 中的所有记录及其在 TABLEA 或 TABLEB 中的等效值。所以表 A 和 B 连接到表 c 记录。所以我们需要使用左连接(你会得到表C的所有记录和表A和B的公共记录)。更多信息请参考link

    SELECT 
        ifnull(A.FNAME,""), 
        ifnull(B.MNAME,""),
        ifnull(C.LNAME,"")
    FROM 
        TABLEA AS A 
    LEFT JOIN 
        TABLEB AS B
    ON 
        A.ID = B.ID
    LEFT JOIN 
        TABLEC AS C
    ON 
        C.ID = B.ID
    

    【讨论】:

    • 表 a 没有 id 2 和 5,因此结果中会丢失。
    【解决方案3】:

    问题是您没有包含所有 ID 的表。所以你必须做一个。然后你就可以加入了。

    使用此查询获取所有 id

    SELECT ID FROM TABLEA
    UNION 
    SELECT ID FROM TABLEB
    UNION 
    SELECT ID FROM TABLEC
    

    现在我们可以使用这个查询/id 表来加入其他人

    SELECT A.FNAME, B.MNAME, C.LNAME
    FROM (
      SELECT ID FROM TABLEA
      UNION 
      SELECT ID FROM TABLEB
      UNION 
      SELECT ID FROM TABLEC
    ) I
    LEFT JOIN TABLEA A ON I.ID = A.ID
    LEFT JOIN TABLEB B ON I.ID = B.ID
    LEFT JOIN TABLEC C ON I.ID = C.ID
    

    当然,如果您有另一个包含所有 ID 列表的表 (TABLEID),您可以使用它来代替上面的子查询。可能是您的模型有这样的表,但除非您告诉我们,否则我们不会知道。

    【讨论】:

      【解决方案4】:

      正如您所说“选择 TABLEC 中的所有记录及其在 TABLEA 或 TABLEB 中的等效值”,因此您需要将 C 与 A 和 C 与 B 连接起来。因此您需要将查询更新为:

      SELECT A.FNAME, B.MNAME, C.LNAME
      FROM TABLEC AS C RIGHT JOIN TABLEB AS B
          ON B.ID = C.ID
      RIGHT JOIN TABLEA AS A
          ON C.ID = A.ID
      

      如果你想要A、B和C中存在的所有记录。没有值的记录会显示NULL值,

      SELECT  A.FNAME, B.MNAME, C.LNAME
      FROM (
      TABLEA AS A
      LEFT JOIN TABLEB AS B ON B.ID = A.ID
      )
      RIGHT JOIN TABLEC AS C ON ( C.ID = B.ID
      OR B.ID = NULL 
      OR A.ID = C.ID ) 
      WHERE 1
      

      【讨论】:

      • 表 c 没有 ids 2 和 4,因此结果中会丢失它们。
      【解决方案5】:
      1. 完美使用它
      
      
          SELECT A.FNAME, B.MNAME, C.LNAME
          FROM TABLEC AS C 
          LEFT JOIN TABLEA AS A ON (A.ID = C.ID)
          LEFT JOIN TABLEB AS B ON (B.ID = C.ID)
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-07-28
        • 1970-01-01
        • 2021-03-10
        • 2023-04-09
        • 2013-08-14
        • 2012-03-19
        • 1970-01-01
        相关资源
        最近更新 更多