簡體   English   中英

MySQL的加入-左,右或外?

[英]mysql JOIN - Left, right or Outer?

我有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的第三列是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 |
+--------------+------------+----------+

這是更新的查詢。 select table1.v_dt, table1.e_dt, table2.col_b from table1 inner join table2 on table1.symbol=table2.symbol group by v_dt, e_dt; 為了進一步縮小結果范圍,我還運行了
select table1.v_dt, table1.e_dt, table2.col_b from table1 inner join table2 on table1.symbol='P00055000' group by v_dt, e_dt; 但我仍然得到相同的結果,然后

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中符合連接條件的行

對於在連接表的LEFT / RIGHT聯接中選擇的任何列,如果該行不符合聯接條件,則將出現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中都匹配的記錄,而忽略其余所有記錄。 希望這可以為您清除一切。

我認為您正在尋找inner join 左聯接返回table1中的所有記錄以及匹配的table2值;如果沒有匹配的table2,則返回null。

內部聯接返回兩組中每個匹配對(基於聯接條件),但不返回沒有匹配項的任何記錄。

http://en.wikipedia.org/wiki/Join_(SQL)

您獲得這么多記錄的原因是因為聯接返回兩個表的笛卡爾積。 例如,如果您有一個包含10條記錄的表,而另一個包含20條記錄的表,則最終有200條記錄。 顯然,這本身是沒有用的,因此您添加聯接條件以僅返回邏輯上並在一起的記錄(通常基於外鍵關系)。 因此對於:

Table1 - Table1Key, Table1Value
Table2 - Table2Key, Table1KeyReference, Table2Value

and the values

Table1
1,'1'
2,'2'
3,'3'
4,'4'
5,'5'

Table2
1,1,'1-1'
2,1,'1-2'
3,2,'2-3'

有了這些數據,下面的語句

select *
    from Table1
        inner join Table2

退貨

Table1Key,Table1Value,Table2Key,Table1KeyReference, Table2Value
1,'1',1,1,'1-1'
1,'1',2,1,'1-2'
1,'1',3,2,'2-3'
2,'2',1,1,'1-1'
2,'2',2,1,'1-2'
2,'2',3,2,'2-3'
....

等等,從這15個組合中,只有“正確”的,因此我們需要添加一個連接條件:

select *
    from Table1
        inner join Table2 on(Table1.Table1Key=Table2.Table1KeyReference)

哪個返回:

1,'1',1,1,'1-1'
1,'1',2,1,'1-2'
2,'2',3,2,'2-3'

它僅返回Table2中的3的原因是Table2中的每一行都對應於1,而Table1中僅一行。

您遇到的問題是您尚未在兩個表之間定義該關系。 如果第二個表中有40個P00055000符號,而第一個表中有2個帶有該符號的符號,那么從P00055000中將獲得80個結果。 如果有40個不同的符號,每個符號在第二個表中又有40行,而在第一個表中又有2行,那么最終將得到3200行,依此類推。其中很多可能是無意義的數據,這是因為還沒有明確定義兩個表之間的關系。

所以,總而言之,選擇時想要什么結果? 對於表1中的給定行,如果將其與表2中的每一行連接在一起,則要返回哪些行? 從那里,您應該能夠制定正確的加入條件。 如果這兩行緊密相關(父級子級等),則應考慮重構表以結合主/外鍵關系並刪除重復的數據。

順便說一句,我假設這些不是您的實際表名和字段名。 如果是這樣,請將其更改為有意義的內容。 列名的長度不會影響查詢性能,但是會使共享,討論和修改代碼變得更加輕松。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM