mysql JOIN - 左连接、右连接还是外连接?

标签 mysql

我有 2 个表,其中包含以下列: 表1

+--------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| symbol | varchar(45) | NO | MUL | NULL | |
| v_dt | date | NO | | NULL | |
| e_dt | date | NO | | NULL | |
| col_s | decimal(10,4) | NO | | NULL | |
| col_o | decimal(10,4) | NO | | NULL | |
| col_b | decimal(10,4) | NO | | NULL | |
| col_a | decimal(10,4) | NO | | NULL | |
| col_l | decimal(10,4) | NO | | NULL | |
| col_v | bigint(20) | NO | | NULL | |
| col_t | enum('a','b') | NO | | NULL | |
+--------------+---------------+------+-----+---------+----------------+

和表 2:

+------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+-------+
| t_date | date | NO | PRI | NULL | |
| e_date | date | NO | | NULL | |
| symbol | varchar(45) | NO | PRI | NULL | |
| col_i | decimal(10,6) | NO | | NULL | |
| col_b | decimal(10,6) | NO | | NULL | |
| col_d | decimal(10,6) | NO | | NULL | |
| col_g | decimal(10,6) | NO | | NULL | |
| col_v | decimal(10,6) | NO | | NULL | |
| col_t | decimal(10,6) | NO | | NULL | |
| col_r | decimal(10,6) | NO | | NULL | |
+------------+---------------+------+-----+---------+-------+

我想检索table1.col_b、table1.col_a和table2.col_d 所以,我写了以下内容

SELECT col_b, col_a, col_d FROM table1 LEFT JOIN table2 ON table1.symbol=table2.symbol;

但它没有返回应有的 40 行,而是继续运行以检索具有不相关数据的 4000 行,因此我猜测我错误地编写了 JOIN。 你可以吗?让我知道编写此代码以检索所需数据的正确方法是什么。谢谢! INNER JOIN 的结果(我更改了查询以包含日期,以便结果更有意义,我希望)

SELECT v_dt, e_dt, col_d FROM table1 INNER JOIN table2 ON table1.symbol=table2.symbol;

| 2011-09-26   | 2011-11-18 |   2.030130 |
| 2011-09-27   | 2011-11-18 |   2.030130 |
| 2011-09-28   | 2011-11-18 |   2.030130 |
| 2011-09-29   | 2011-11-18 |   2.030130 |
| 2011-09-30   | 2011-11-18 |   2.030130 |
| 2011-10-03   | 2011-11-18 |   2.030130 |
| 2011-10-04   | 2011-11-18 |   2.030130 |
| 2011-10-05   | 2011-11-18 |   2.030130 |
| 2011-10-06   | 2011-11-18 |   2.030130 |
| 2011-10-07   | 2011-11-18 |   2.030130 |
| 2011-10-10   | 2011-11-18 |   2.030130 |
| 2011-10-11   | 2011-11-18 |   2.030130 |
| 2011-10-12   | 2011-11-18 |   2.030130 |
| 2011-10-13   | 2011-11-18 |   2.030130 |
| 2011-10-14   | 2011-11-18 |   2.030130 |
| 2011-08-09   | 2011-11-18 |   1.628250 |
| 2011-08-10   | 2011-11-18 |   1.628250 |
| 2011-08-11   | 2011-11-18 |   1.628250 |
| 2011-08-12   | 2011-11-18 |   1.628250 |
| 2011-08-15   | 2011-11-18 |   1.628250 |
| 2011-08-16   | 2011-11-18 |   1.628250 |
| 2011-08-17   | 2011-11-18 |   1.628250 |
| 2011-08-18   | 2011-11-18 |   1.628250 |
| 2011-08-19   | 2011-11-18 |   1.628250 |
| 2011-08-22   | 2011-11-18 |   1.628250 |
| 2011-08-24   | 2011-11-18 |   1.628250 |
| 2011-08-25   | 2011-11-18 |   1.628250 |
| 2011-08-26   | 2011-11-18 |   1.628250 |
| 2011-08-29   | 2011-11-18 |   1.628250 |
| 2011-08-30   | 2011-11-18 |   1.628250 |
| 2011-08-31   | 2011-11-18 |   1.628250 |
| 2011-09-01   | 2011-11-18 |   1.628250 |
| 2011-09-02   | 2011-11-18 |   1.628250 |
| 2011-09-06   | 2011-11-18 |   1.628250 |
| 2011-09-07   | 2011-11-18 |   1.628250 |
| 2011-09-08   | 2011-11-18 |   1.628250 |
| 2011-09-09   | 2011-11-18 |   1.628250 |
| 2011-09-13   | 2011-11-18 |   1.628250 |
| 2011-09-14   | 2011-11-18 |   1.628250 |
| 2011-09-15   | 2011-11-18 |   1.628250 |
| 2011-09-16   | 2011-11-18 |   1.628250 |
| 2011-09-19   | 2011-11-18 |   1.628250 |
| 2011-09-20   | 2011-11-18 |   1.628250 |
| 2011-09-21   | 2011-11-18 |   1.628250 |
| 2011-09-22   | 2011-11-18 |   1.628250 |
| 2011-09-23   | 2011-11-18 |   1.628250 |
| 2011-09-26   | 2011-11-18 |   1.628250 |
| 2011-09-27   | 2011-11-18 |   1.628250 |
| 2011-09-28   | 2011-11-18 |   1.628250 |
| 2011-09-29   | 2011-11-18 |   1.628250 |
| 2011-09-30   | 2011-11-18 |   1.628250 |
| 2011-10-03   | 2011-11-18 |   1.628250 |
| 2011-10-04   | 2011-11-18 |   1.628250 |
| 2011-10-05   | 2011-11-18 |   1.628250 |
| 2011-10-06   | 2011-11-18 |   1.628250 |
| 2011-10-07   | 2011-11-18 |   1.628250 |
| 2011-10-10   | 2011-11-18 |   1.628250 |
| 2011-10-11   | 2011-11-18 |   1.628250 |
| 2011-10-12   | 2011-11-18 |   1.628250 |
| 2011-10-13   | 2011-11-18 |   1.628250 |
| 2011-10-14   | 2011-11-18 |   1.628250 |
| 2011-08-09   | 2011-11-18 |   1.254390 |
| 2011-08-10   | 2011-11-18 |   1.254390 |
| 2011-08-11   | 2011-11-18 |   1.254390 |
| 2011-08-12   | 2011-11-18 |   1.254390 |
| 2011-08-15   | 2011-11-18 |   1.254390 |
| 2011-08-16   | 2011-11-18 |   1.254390 |
| 2011-08-17   | 2011-11-18 |   1.254390 |
| 2011-08-18   | 2011-11-18 |   1.254390 |
| 2011-08-19   | 2011-11-18 |   1.254390 |
| 2011-08-22   | 2011-11-18 |   1.254390 |
| 2011-08-24   | 2011-11-18 |   1.254390 |
| 2011-08-25   | 2011-11-18 |   1.254390 |
| 2011-08-26   | 2011-11-18 |   1.254390 |
| 2011-08-29   | 2011-11-18 |   1.254390 |
| 2011-08-30   | 2011-11-18 |   1.254390 |
| 2011-08-31   | 2011-11-18 |   1.254390 |
| 2011-09-01   | 2011-11-18 |   1.254390 |
| 2011-09-02   | 2011-11-18 |   1.254390 |
| 2011-09-06   | 2011-11-18 |   1.254390 |
| 2011-09-07   | 2011-11-18 |   1.254390 |
| 2011-09-08   | 2011-11-18 |   1.254390 |
| 2011-09-09   | 2011-11-18 |   1.254390 |
| 2011-09-13   | 2011-11-18 |   1.254390 |
| 2011-09-14   | 2011-11-18 |   1.254390 |
| 2011-09-15   | 2011-11-18 |   1.254390 |
| 2011-09-16   | 2011-11-18 |   1.254390 |
| 2011-09-19   | 2011-11-18 |   1.254390 |
| 2011-09-20   | 2011-11-18 |   1.254390 |
| 2011-09-21   | 2011-11-18 |   1.254390 |
| 2011-09-22   | 2011-11-18 |   1.254390 |
| 2011-09-23   | 2011-11-18 |   1.254390 |
| 2011-09-26   | 2011-11-18 |   1.254390 |
| 2011-09-27   | 2011-11-18 |   1.254390 |
| 2011-09-28   | 2011-11-18 |   1.254390 |
| 2011-09-29   | 2011-11-18 |   1.254390 |
| 2011-09-30   | 2011-11-18 |   1.254390 |
| 2011-10-03   | 2011-11-18 |   1.254390 |
| 2011-10-04   | 2011-11-18 |   1.254390 |
| 2011-10-05   | 2011-11-18 |   1.254390 |
| 2011-10-06   | 2011-11-18 |   1.254390 |
| 2011-10-07   | 2011-11-18 |   1.254390 |
| 2011-10-10   | 2011-11-18 |   1.254390 |
| 2011-10-11   | 2011-11-18 |   1.254390 |
| 2011-10-12   | 2011-11-18 |   1.254390 |
| 2011-10-13   | 2011-11-18 |   1.254390 |
| 2011-10-14   | 2011-11-18 |   1.254390 |
| 2011-08-09   | 2011-11-18 |   1.019710 |
| 2011-08-10   | 2011-11-18 |   1.019710 |
| 2011-08-11   | 2011-11-18 |   1.019710 |
| 2011-08-12   | 2011-11-18 |   1.019710 |
| 2011-08-15   | 2011-11-18 |   1.019710 |
| 2011-08-16   | 2011-11-18 |   1.019710 |
| 2011-08-17   | 2011-11-18 |   1.019710 |
| 2011-08-18   | 2011-11-18 |   1.019710 |
| 2011-08-19   | 2011-11-18 |   1.019710 |

我所希望得到的是表 1 中的以下 2 列和表 2 中的第三列 col_d。因此我预计有 45 行。

+--------------+------------+
| 2011-08-09   | 2013-01-18 |
| 2011-08-10   | 2013-01-18 |
| 2011-08-11   | 2013-01-18 |
| 2011-08-12   | 2013-01-18 |
| 2011-08-15   | 2013-01-18 |
| 2011-08-16   | 2013-01-18 |
| 2011-08-17   | 2013-01-18 |
| 2011-08-18   | 2013-01-18 |
| 2011-08-19   | 2013-01-18 |
| 2011-08-22   | 2013-01-18 |
| 2011-08-24   | 2013-01-18 |
| 2011-08-25   | 2013-01-18 |
| 2011-08-26   | 2013-01-18 |
| 2011-08-29   | 2013-01-18 |
| 2011-08-30   | 2013-01-18 |
| 2011-08-31   | 2013-01-18 |
| 2011-09-01   | 2013-01-18 |
| 2011-09-02   | 2013-01-18 |
| 2011-09-06   | 2013-01-18 |
| 2011-09-07   | 2013-01-18 |
| 2011-09-08   | 2013-01-18 |
| 2011-09-09   | 2013-01-18 |
| 2011-09-13   | 2013-01-18 |
| 2011-09-14   | 2013-01-18 |
| 2011-09-15   | 2013-01-18 |
| 2011-09-16   | 2013-01-18 |
| 2011-09-20   | 2013-01-18 |
| 2011-09-21   | 2013-01-18 |
| 2011-09-22   | 2013-01-18 |
| 2011-09-23   | 2013-01-18 |
| 2011-09-26   | 2013-01-18 |
| 2011-09-27   | 2013-01-18 |
| 2011-09-28   | 2013-01-18 |
| 2011-09-29   | 2013-01-18 |
| 2011-09-30   | 2013-01-18 |
| 2011-10-03   | 2013-01-18 |
| 2011-10-04   | 2013-01-18 |
| 2011-10-05   | 2013-01-18 |
| 2011-10-06   | 2013-01-18 |
| 2011-10-07   | 2013-01-18 |
| 2011-10-10   | 2013-01-18 |
| 2011-10-11   | 2013-01-18 |
| 2011-10-12   | 2013-01-18 |
| 2011-10-13   | 2013-01-18 |
| 2011-10-14   | 2013-01-18 |
+--------------+------------+
45 rows in set (0.02 sec)

添加 GROUP BY v_dt, e_dt 使其减少到 45 行,并且 table1 的列是正确的。唯一的问题是它现在为 table2.col_d 显示相同的值(5.530000),这不是它应该的值:-(

+--------------+------------+----------+
| 2011-08-09   | 2013-01-18 | 5.530000 |
| 2011-08-10   | 2013-01-18 | 5.530000 |
| 2011-08-11   | 2013-01-18 | 5.530000 |
| 2011-08-12   | 2013-01-18 | 5.530000 |
| 2011-08-15   | 2013-01-18 | 5.530000 |
| 2011-08-16   | 2013-01-18 | 5.530000 |
| 2011-08-17   | 2013-01-18 | 5.530000 |
| 2011-08-18   | 2013-01-18 | 5.530000 |
| 2011-08-19   | 2013-01-18 | 5.530000 |
| 2011-08-22   | 2013-01-18 | 5.530000 |
| 2011-08-24   | 2013-01-18 | 5.530000 |
| 2011-08-25   | 2013-01-18 | 5.530000 |
| 2011-08-26   | 2013-01-18 | 5.530000 |
| 2011-08-29   | 2013-01-18 | 5.530000 |
| 2011-08-30   | 2013-01-18 | 5.530000 |
| 2011-08-31   | 2013-01-18 | 5.530000 |
| 2011-09-01   | 2013-01-18 | 5.530000 |
| 2011-09-02   | 2013-01-18 | 5.530000 |
| 2011-09-06   | 2013-01-18 | 5.530000 |
| 2011-09-07   | 2013-01-18 | 5.530000 |
| 2011-09-08   | 2013-01-18 | 5.530000 |
| 2011-09-09   | 2013-01-18 | 5.530000 |
| 2011-09-13   | 2013-01-18 | 5.530000 |
| 2011-09-14   | 2013-01-18 | 5.530000 |
| 2011-09-15   | 2013-01-18 | 5.530000 |
| 2011-09-16   | 2013-01-18 | 5.530000 |
| 2011-09-20   | 2013-01-18 | 5.530000 |
| 2011-09-21   | 2013-01-18 | 5.530000 |
| 2011-09-22   | 2013-01-18 | 5.530000 |
| 2011-09-23   | 2013-01-18 | 5.530000 |
| 2011-09-26   | 2013-01-18 | 5.530000 |
| 2011-09-27   | 2013-01-18 | 5.530000 |
| 2011-09-28   | 2013-01-18 | 5.530000 |
| 2011-09-29   | 2013-01-18 | 5.530000 |
| 2011-09-30   | 2013-01-18 | 5.530000 |
| 2011-10-03   | 2013-01-18 | 5.530000 |
| 2011-10-04   | 2013-01-18 | 5.530000 |
| 2011-10-05   | 2013-01-18 | 5.530000 |
| 2011-10-06   | 2013-01-18 | 5.530000 |
| 2011-10-07   | 2013-01-18 | 5.530000 |
| 2011-10-10   | 2013-01-18 | 5.530000 |
| 2011-10-11   | 2013-01-18 | 5.530000 |
| 2011-10-12   | 2013-01-18 | 5.530000 |
| 2011-10-13   | 2013-01-18 | 5.530000 |
| 2011-10-14   | 2013-01-18 | 5.530000 |
+--------------+------------+----------+

这是更新后的查询。 从 table1.symbol=table2.symbol group by v_dt、e_dt 上的 table1 内连接 table2 中选择 table1.v_dt、table1.e_dt、table2.col_b; 为了进一步缩小结果,我还跑了
从 table1.symbol='P00055000' group by v_dt、e_dt 上的 table1 内连接 table2 中选择 table1.v_dt、table1.e_dt、table2.col_b; 但我仍然得到相同的结果,然后

select symbol, count(*) from table2 where symbol='P00055000' group by symbol;

+--------------------+----------+
| P00055000 |       40 |
+--------------------+----------+
1 row in set (0.02 sec)

最佳答案

如果您有两个表 A 和 B:

  • A LEFT JOIN B = 选择所有行 A 以及 B 中符合联接条件的所有行,如果 B 不符合联接条件,则选择 NULL
  • A RIGHT JOIN B = 选择所有行 B 以及 A 中符合联接条件的任何行,如果 A 不符合联接条件,则选择 NULL
  • A INNER JOIN B = 仅选择 A 和 B 中符合连接条件的行

对于连接表的左/右连接中选择的任何列,如果该行与连接条件不匹配,则将出现 NULL 值。


例如,假设我们有两张表

Table A (id, name, description)
Table B (id, a_id, group_id, date)

当我们运行下面的LEFT JOIN时,如果在B表中找不到记录,我们预计查询结果将为B.group_id和B.date返回NULL。

SELECT A.id, A.name, A.description, B.group_id, B.date FROM A
LEFT JOIN B ON B.a_id=A.id

结果

id | name | description | group_id | date
1  | Test | Test        | 2        | 2011-3-4
2  | Test | Test        | NULL     | NULL

可以看到,第一行成功地在 A 和 B 中找到了符合连接条件的记录。另一方面,第 2 行在 B 中找不到匹配的记录,因此添加了 NULL 值。


让我们看一下RIGHT JOIN。这实际上是 LEFT JOIN 的逆操作。我们期望 B 中的所有记录都包含其数据,但如果 A 中的记录不匹配,它将包含 NULL。

SELECT A.id, A.name, A.description, B.group_id, B.date FROM A
RIGHT JOIN B ON B.a_id=A.id

结果

id   | name | description | group_id | date
1    | Test | Test        | 2        | 2011-3-4
NULL | NULL | NULL        | 3        | 2011-5-6

如您所见,第一行成功地在 A 和 B 中找到了符合连接条件的记录(与 LEFT JOIN 相同)。另一方面,第 2 行在 A 中找不到匹配的记录,因此添加了 NULL 值。


最后让我们看看INNER JOIN。 INNER JOIN 通常是最有用的联接,因为它仅返回在 A 和 B 中匹配的记录,这通常是您要查找的内容

SELECT A.id, A.name, A.description, B.group_id, B.date FROM A
INNER JOIN B ON B.a_id=A.id

结果

id   | name | description | group_id | date
1    | Test | Test        | 2        | 2011-3-4

现在我们只返回 A 和 B 中都匹配的记录,而忽略其余的记录。希望这能为您解决问题。

关于mysql JOIN - 左连接、右连接还是外连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7784887/

相关文章:

php - 向所有订阅者(所有用户)发送电子邮件 PHP 和 MYSQL(每天 25,000 封邮件)

php - 为什么有时 php 返回像纯文本 HTTP/1.1 200 OK 这样的 http header ,而它应该只返回 json?

c# - 在 C# 中从 MySql 获取两个日期之间的数据

php - 基本信息保存在cookie中还是一直在mysql中获取?

php - 在执行函数之前检查sql中的日期时间

mysql - 带有自动触发器的 SQL 继承

mysql - 仅当超过 n 行时才删除值较低的行

MySQL - 根据先前的序列选择序列中的下一项

mysql - 如何使用 Gradle 导入 MySQL 并连接到 JavaFX

mysql - 重音词不敏感搜索