这个左连接如何写?

测试数据产生

CREATE TABLE `tb` (
  `id` int(11) NOT NULL AUTO_INCREMENT ,
  `name` text ,
  `year` int(2) ,
  `num` int(5) ,
  PRIMARY KEY (`id`)
);

数据写入

  
INSERT INTO tb (id, name,year,num) VALUES ('1', 'a','19', 500);
INSERT INTO tb (id, name,year,num) VALUES ('2', 'a','18', 400);
INSERT INTO tb (id, name,year,num) VALUES ('3', 'b','19', 400);
INSERT INTO tb (id, name,year,num) VALUES ('4', 'b','18', 200);
INSERT INTO tb (id, name,year,num) VALUES ('5', 'c','19', 400);
INSERT INTO tb (id, name,year,num) VALUES ('6', 'c','18', 100);

可以产生两个表


SELECT `name`, `num` FROM `tb` WHERE `year` = 19;
+------+------+
| name | num  |
+------+------+
| a    |  500 |
| b    |  400 |
| c    |  400 |
+------+------+
3 rows in set (0.00 sec)

MariaDB [hksec]> SELECT `name`, `num` FROM `tb` WHERE `year` = 18;
+------+------+
| name | num  |
+------+------+
| a    |  400 |
| b    |  200 |
| c    |  100 |
+------+------+
3 rows in set (0.00 sec)

现在我需要连接两个表:


+------+------+
| name | num  | name  num
+------+------+
| a    |  500 |a      400      
| b    |  400 |b      200
| c    |  400 |c      100
+------+------+

为何不可以这样写


    SELECT `name`, `num`
    FROM `tb`  a
    WHERE `year` = 19
LEFT JOIN
    (
    SELECT `name`, `num`
    FROM `tb` b
    WHERE `year` = 18
    )  ON a.`name` = b.`name`;
    
    

zltl给出了写法,也得出了结果,但我还是有点不明白。
为何

SELECT `name`, `num`
FROM `tb`
WHERE `year` = 19
) a
LEFT JOIN
(
SELECT `name`, `num`
FROM `tb`
WHERE `year` = 18
) b ON a.`name` = b.`name`;

不能给出正确结果?请解释原因?

请看
https://dev.mysql.com/doc/ref...

有这个例子:

SELECT t1.name, t2.salary
FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;

它就没有写成
select * from
SELECT t1.name, t2.salary
FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;

阅读 2.2k
2 个回答
SELECT * FROM (
    SELECT `name`, `num`
    FROM `tb`
    WHERE `year` = 19
    ) a
LEFT JOIN
    (
    SELECT `name`, `num`
    FROM `tb`
    WHERE `year` = 18
    ) b ON a.`name` = b.`name`;

因为语法不对,JOIN 不是这么用的,参考
https://dev.mysql.com/doc/ref...
https://dev.mysql.com/doc/ref...

看上面 Select syntax 和 Join syntax 规范。先看Select syntax, FROM 后面只能跟 table_references 。转到 Join syntax, joined_table 可以是一个 table_references , {LEFT|RIGHT} [OUTER] JOIN 前后只能是 table_reference 。你的代码里面 SELECT name, num FROM tb a WHERE year = 19 不是 table_references

简要地说,你要 LEFT JOIN,就要看LEFT JOIN的语法:

SELECT xxxxx FROM 
  table_references LEFT JOIN table_references
  ON xxxxx
  WHERE xxxxx

这总体是一个 SELECT 语法,SELECT 后面的 xxx 是整体要查询出的列。 再之后,注意格式和顺序不能乱。_table_references_ 必须是一个表,临时表也可以,子查询也可以,JOIN 出来的临时表也可以。JOIN 两个表之后是ON,也就是 JOIN 的条件。 最后是这个查询的WHERE。

你的需求还可以如下实现

SELECT a.name, a.num, b.name, b.num
    FROM 
    /* 这是一个表,起个别名为 a,这样 SELECT 语句就可以用a来表示它 */
    `tb`  a
    LEFT JOIN
    /* 下面是一个子查询的临时表,别名是 b */
    (
    SELECT *
    FROM `tb`
    WHERE `year` = 18
    ) b 
    /* ON xxxxx */
    ON a.name=b.name
WHERE a.`year` = 19

或者

SELECT a.name, a.num, b.name, b.num
    FROM tb  a 
    LEFT JOIN
    tb b
    ON a.name=b.name
WHERE a.`year` = 19 AND b.year = 18

语句符合语法规范才可以运行。

是不是应该吧 where 放在 left join 后面啊?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题