Hướng dẫn join mysql tutorial - tham gia hướng dẫn mysql

13.2.10.2 & nbsp; tham gia mệnh đề

MySQL hỗ trợ cú pháp

SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                 ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
5 sau đây cho phần
SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                 ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
6 của các câu lệnh
SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                 ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
7 và các câu lệnh
SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                 ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
8 và
SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                 ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
9:

table_references:
    escaped_table_reference [, escaped_table_reference] ...

escaped_table_reference: {
    table_reference
  | { OJ table_reference }
}

table_reference: {
    table_factor
  | joined_table
}

table_factor: {
    tbl_name [PARTITION (partition_names)]
        [[AS] alias] [index_hint_list]
  | [LATERAL] table_subquery [AS] alias [(col_list)]
  | ( table_references )
}

joined_table: {
    table_reference {[INNER | CROSS] JOIN | STRAIGHT_JOIN} table_factor [join_specification]
  | table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_specification
  | table_reference NATURAL [INNER | {LEFT|RIGHT} [OUTER]] JOIN table_factor
}

join_specification: {
    ON search_condition
  | USING (join_column_list)
}

join_column_list:
    column_name [, column_name] ...

index_hint_list:
    index_hint [, index_hint] ...

index_hint: {
    USE {INDEX|KEY}
      [FOR {JOIN|ORDER BY|GROUP BY}] ([index_list])
  | {IGNORE|FORCE} {INDEX|KEY}
      [FOR {JOIN|ORDER BY|GROUP BY}] (index_list)
}

index_list:
    index_name [, index_name] ...

Một tham chiếu bảng còn được gọi là một biểu thức tham gia.

Một tham chiếu bảng (khi nó đề cập đến một bảng được phân vùng) có thể chứa một mệnh đề

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

SELECT t1.name, t2.salary
  FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
0, bao gồm danh sách các phân vùng được phân tách bằng dấu phẩy, các phần phụ hoặc cả hai. Tùy chọn này theo tên của bảng và đi trước mọi khai báo bí danh. Hiệu quả của tùy chọn này là các hàng chỉ được chọn từ các phân vùng được liệt kê hoặc các phần phụ. Bất kỳ phân vùng hoặc phân vùng nào không được đặt tên trong danh sách đều bị bỏ qua. Để biết thêm thông tin và ví dụ, xem Phần & NBSP; 24.5, Lựa chọn phân vùng.

Cú pháp của

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

SELECT t1.name, t2.salary
  FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
1 được mở rộng trong MySQL so với SQL tiêu chuẩn. Tiêu chuẩn chỉ chấp nhận
SELECT t1.name, t2.salary
  FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;

SELECT t1.name, t2.salary
  FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
2, không phải là danh sách chúng bên trong một cặp dấu ngoặc đơn.

Đây là một phần mở rộng bảo thủ nếu mỗi dấu phẩy trong danh sách các mục

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

SELECT t1.name, t2.salary
  FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
2 được coi là tương đương với một lần nối bên trong. Ví dụ:

SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                 ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)

tương đương với:

SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                 ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)

Trong MySQL,

SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                 ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
5,
SELECT t1.name, t2.salary
  FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;

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

SELECT t1.name, t2.salary
  FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
6 là tương đương cú pháp (chúng có thể thay thế lẫn nhau). Trong SQL tiêu chuẩn, chúng không tương đương.
SELECT t1.name, t2.salary
  FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;

SELECT t1.name, t2.salary
  FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
6 được sử dụng với mệnh đề
SELECT t1.name, t2.salary
  FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;

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

SELECT t1.name, t2.salary
  FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
9 được sử dụng khác.

Nói chung, dấu ngoặc đơn có thể bị bỏ qua trong các biểu thức tham gia chỉ chứa các hoạt động tham gia bên trong. MySQL cũng hỗ trợ tham gia lồng nhau. Xem Phần & NBSP; 8.2.1.8, Tối ưu hóa tham gia.

Gợi ý chỉ mục có thể được chỉ định để ảnh hưởng đến cách trình tối ưu hóa MySQL sử dụng các chỉ mục. Để biết thêm thông tin, xem Phần & NBSP; 8.9.4, Gợi ý Chỉ số. Gợi ý của trình tối ưu hóa và biến hệ thống

SELECT * FROM (SELECT 1, 2, 3) AS t1;
0 là những cách khác để ảnh hưởng đến việc sử dụng các chỉ mục tối ưu hóa. Xem Phần & NBSP; 8.9.3, Gợi ý của Trình tối ưu hóa, và Phần & NBSP; 8.9.2, Tối ưu hóa chuyển đổi có thể chuyển đổi.

Danh sách sau đây mô tả các yếu tố chung cần tính đến khi viết tham gia:

  • Một tham chiếu bảng có thể được đặt bí danh bằng cách sử dụng

    SELECT * FROM (SELECT 1, 2, 3) AS t1;
    1 là
    SELECT * FROM (SELECT 1, 2, 3) AS t1;
    2 hoặc
    SELECT * FROM (SELECT 1, 2, 3) AS t1;
    3:

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

    SELECT * FROM (SELECT 1, 2, 3) AS t1;
    4 còn được gọi là bảng dẫn xuất hoặc truy vấn con trong mệnh đề
    SELECT * FROM (SELECT 1, 2, 3) AS t1;
    5. Xem Phần & NBSP; 13.2.11.8, Bảng dẫn xuất. Các truy vấn con như vậy phải bao gồm một bí danh để đưa ra kết quả con một tên bảng và có thể tùy ý bao gồm một danh sách các tên cột bảng trong ngoặc đơn. Một ví dụ tầm thường sau:must include an alias to give the subquery result a table name, and may optionally include a list of table column names in parentheses. A trivial example follows:

    SELECT * FROM (SELECT 1, 2, 3) AS t1;
  • Số lượng bảng tối đa có thể được tham chiếu trong một lần tham gia là 61. Điều này bao gồm một lần tham gia được xử lý bằng cách hợp nhất các bảng và chế độ xem trong mệnh đề

    SELECT * FROM (SELECT 1, 2, 3) AS t1;
    5 vào khối truy vấn bên ngoài (xem Phần & NBSP; 8.2.2.2 Tài liệu tham khảo và biểu thức bảng phổ biến với sự hợp nhất hoặc vật chất hóa).

  • SELECT t1.name, t2.salary
      FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;
    
    SELECT t1.name, t2.salary
      FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
    6 và
    SELECT * FROM (SELECT 1, 2, 3) AS t1;
    8 (dấu phẩy) tương đương về mặt ngữ nghĩa khi không có điều kiện tham gia: cả hai sản xuất một sản phẩm Cartesian giữa các bảng được chỉ định (nghĩa là mỗi và mỗi hàng trong bảng đầu tiên được nối với từng hàng trong bảng thứ hai) .

    Tuy nhiên, mức độ ưu tiên của toán tử dấu phẩy ít hơn so với

    SELECT t1.name, t2.salary
      FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;
    
    SELECT t1.name, t2.salary
      FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
    6,
    SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;
    0,
    SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;
    1, v.v. Nếu bạn kết hợp dấu phẩy tham gia với các loại tham gia khác khi có điều kiện tham gia, có thể xảy ra lỗi của mẫu
    SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;
    2 'trong mệnh đề' ON 'trên mệnh đề'. Thông tin về xử lý vấn đề này được đưa ra sau trong phần này.

  • SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;
    3 được sử dụng với
    SELECT t1.name, t2.salary
      FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;
    
    SELECT t1.name, t2.salary
      FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
    8 là bất kỳ biểu thức có điều kiện nào của hình thức có thể được sử dụng trong mệnh đề
    SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;
    5. Nói chung, mệnh đề
    SELECT t1.name, t2.salary
      FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;
    
    SELECT t1.name, t2.salary
      FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
    8 phục vụ cho các điều kiện chỉ định cách tham gia các bảng và mệnh đề
    SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;
    5 hạn chế các hàng sẽ bao gồm trong tập kết quả.

  • Nếu không có hàng phù hợp cho bảng phù hợp trong phần

    SELECT t1.name, t2.salary
      FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;
    
    SELECT t1.name, t2.salary
      FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
    8 hoặc
    SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;
    9 trong
    SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;
    1, một hàng với tất cả các cột được đặt thành
    a LEFT JOIN b USING (c1, c2, c3)
    1 được sử dụng cho bảng bên phải. Bạn có thể sử dụng thực tế này để tìm các hàng trong một bảng không có đối tác trong một bảng khác:

    SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;

    Ví dụ này tìm thấy tất cả các hàng trong

    a LEFT JOIN b USING (c1, c2, c3)
    2 với giá trị
    a LEFT JOIN b USING (c1, c2, c3)
    3 không có trong
    a LEFT JOIN b USING (c1, c2, c3)
    4 (nghĩa là tất cả các hàng trong
    a LEFT JOIN b USING (c1, c2, c3)
    2 không có hàng tương ứng trong
    a LEFT JOIN b USING (c1, c2, c3)
    4). Xem Phần & NBSP; 8.2.1.9, Tối ưu hóa tham gia bên ngoài.

  • Điều khoản

    a LEFT JOIN b USING (c1, c2, c3)
    7) đặt tên cho một danh sách các cột phải tồn tại trong cả hai bảng. Nếu các bảng
    a LEFT JOIN b USING (c1, c2, c3)
    8 và
    a LEFT JOIN b USING (c1, c2, c3)
    9, cả hai đều chứa các cột
    SELECT left_tbl.*
        FROM { OJ left_tbl LEFT OUTER JOIN right_tbl
               ON left_tbl.id = right_tbl.id }
        WHERE right_tbl.id IS NULL;
    0,
    SELECT left_tbl.*
        FROM { OJ left_tbl LEFT OUTER JOIN right_tbl
               ON left_tbl.id = right_tbl.id }
        WHERE right_tbl.id IS NULL;
    1 và
    SELECT left_tbl.*
        FROM { OJ left_tbl LEFT OUTER JOIN right_tbl
               ON left_tbl.id = right_tbl.id }
        WHERE right_tbl.id IS NULL;
    2, các tham gia sau đây sẽ so sánh các cột tương ứng với hai bảng:

    a LEFT JOIN b USING (c1, c2, c3)
  • SELECT left_tbl.*
        FROM { OJ left_tbl LEFT OUTER JOIN right_tbl
               ON left_tbl.id = right_tbl.id }
        WHERE right_tbl.id IS NULL;
    3 của hai bảng được xác định là tương đương về mặt ngữ nghĩa với
    SELECT left_tbl.*
        FROM { OJ left_tbl LEFT OUTER JOIN right_tbl
               ON left_tbl.id = right_tbl.id }
        WHERE right_tbl.id IS NULL;
    4 hoặc
    SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;
    1 với mệnh đề
    SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;
    9 đặt tên cho tất cả các cột tồn tại trong cả hai bảng.

  • SELECT left_tbl.*
        FROM { OJ left_tbl LEFT OUTER JOIN right_tbl
               ON left_tbl.id = right_tbl.id }
        WHERE right_tbl.id IS NULL;
    7 hoạt động tương tự như
    SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;
    1. Để giữ mã di động trên cơ sở dữ liệu, bạn nên sử dụng
    SELECT left_tbl.*
        FROM { OJ left_tbl LEFT OUTER JOIN right_tbl
               ON left_tbl.id = right_tbl.id }
        WHERE right_tbl.id IS NULL;
    9 thay vì
    SELECT left_tbl.*
        FROM { OJ left_tbl LEFT OUTER JOIN right_tbl
               ON left_tbl.id = right_tbl.id }
        WHERE right_tbl.id IS NULL;
    7.

  • Cú pháp

    SELECT * FROM table1, table2;
    
    SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id;
    
    SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id;
    
    SELECT * FROM table1 LEFT JOIN table2 USING (id);
    
    SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
      LEFT JOIN table3 ON table2.id = table3.id;
    1 được hiển thị trong mô tả cú pháp tham gia chỉ tồn tại để tương thích với ODBC. Các niềng răng xoăn trong cú pháp nên được viết theo nghĩa đen; Chúng không phải là metasyntax như được sử dụng ở nơi khác trong các mô tả cú pháp.

    SELECT left_tbl.*
        FROM { OJ left_tbl LEFT OUTER JOIN right_tbl
               ON left_tbl.id = right_tbl.id }
        WHERE right_tbl.id IS NULL;

    Bạn có thể sử dụng các loại nối khác trong

    SELECT * FROM table1, table2;
    
    SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id;
    
    SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id;
    
    SELECT * FROM table1 LEFT JOIN table2 USING (id);
    
    SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
      LEFT JOIN table3 ON table2.id = table3.id;
    2, chẳng hạn như
    SELECT t1.name, t2.salary
      FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;
    
    SELECT t1.name, t2.salary
      FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
    6 hoặc
    SELECT * FROM table1, table2;
    
    SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id;
    
    SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id;
    
    SELECT * FROM table1 LEFT JOIN table2 USING (id);
    
    SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
      LEFT JOIN table3 ON table2.id = table3.id;
    4. Điều này giúp tương thích với một số ứng dụng của bên thứ ba, nhưng không phải là cú pháp ODBC chính thức.

  • SELECT * FROM table1, table2;
    
    SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id;
    
    SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id;
    
    SELECT * FROM table1 LEFT JOIN table2 USING (id);
    
    SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
      LEFT JOIN table3 ON table2.id = table3.id;
    5 tương tự như
    SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    5, ngoại trừ bảng bên trái luôn được đọc trước bảng bên phải. Điều này có thể được sử dụng cho những trường hợp (một vài) trường hợp mà trình tối ưu hóa tham gia xử lý các bảng theo thứ tự dưới mức tối ưu.

Một số ví dụ tham gia:

SELECT * FROM table1, table2;

SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id;

SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id;

SELECT * FROM table1 LEFT JOIN table2 USING (id);

SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
  LEFT JOIN table3 ON table2.id = table3.id;

Các kết nối tự nhiên và tham gia với

SELECT left_tbl.*
  FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
  WHERE right_tbl.id IS NULL;
9, bao gồm các biến thể tham gia bên ngoài, được xử lý theo tiêu chuẩn SQL: 2003:

  • Các cột dự phòng của tham gia

    SELECT * FROM table1, table2;
    
    SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id;
    
    SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id;
    
    SELECT * FROM table1 LEFT JOIN table2 USING (id);
    
    SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
      LEFT JOIN table3 ON table2.id = table3.id;
    8 không xuất hiện. Hãy xem xét tập hợp các tuyên bố này:

    CREATE TABLE t1 (i INT, j INT);
    CREATE TABLE t2 (k INT, j INT);
    INSERT INTO t1 VALUES(1, 1);
    INSERT INTO t2 VALUES(1, 1);
    SELECT * FROM t1 NATURAL JOIN t2;
    SELECT * FROM t1 JOIN t2 USING (j);

    Trong câu lệnh

    SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    7 đầu tiên, cột
    CREATE TABLE t1 (i INT, j INT);
    CREATE TABLE t2 (k INT, j INT);
    INSERT INTO t1 VALUES(1, 1);
    INSERT INTO t2 VALUES(1, 1);
    SELECT * FROM t1 NATURAL JOIN t2;
    SELECT * FROM t1 JOIN t2 USING (j);
    0 xuất hiện trong cả hai bảng và do đó trở thành một cột nối, do đó, theo SQL tiêu chuẩn, nó chỉ xuất hiện một lần trong đầu ra, không hai lần. Tương tự, trong câu lệnh SELECT thứ hai, cột
    CREATE TABLE t1 (i INT, j INT);
    CREATE TABLE t2 (k INT, j INT);
    INSERT INTO t1 VALUES(1, 1);
    INSERT INTO t2 VALUES(1, 1);
    SELECT * FROM t1 NATURAL JOIN t2;
    SELECT * FROM t1 JOIN t2 USING (j);
    0 được đặt tên trong mệnh đề
    SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;
    9 và chỉ xuất hiện một lần trong đầu ra, không phải hai lần.

    Do đó, các câu lệnh tạo ra đầu ra này:

    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    0

    Việc loại bỏ cột dự phòng và thứ tự cột xảy ra theo SQL tiêu chuẩn, tạo ra thứ tự hiển thị này:

    • Đầu tiên, kết hợp các cột chung của hai bảng được nối, theo thứ tự chúng xảy ra trong bảng đầu tiên

    • Thứ hai, các cột duy nhất cho bảng đầu tiên, theo thứ tự chúng xảy ra trong bảng đó

    • Thứ ba, các cột duy nhất cho bảng thứ hai, theo thứ tự chúng xảy ra trong bảng đó

    Cột kết quả duy nhất thay thế hai cột phổ biến được xác định bằng cách sử dụng hoạt động hợp tác. Đó là, trong hai

    CREATE TABLE t1 (i INT, j INT);
    CREATE TABLE t2 (k INT, j INT);
    INSERT INTO t1 VALUES(1, 1);
    INSERT INTO t2 VALUES(1, 1);
    SELECT * FROM t1 NATURAL JOIN t2;
    SELECT * FROM t1 JOIN t2 USING (j);
    3 và
    CREATE TABLE t1 (i INT, j INT);
    CREATE TABLE t2 (k INT, j INT);
    INSERT INTO t1 VALUES(1, 1);
    INSERT INTO t2 VALUES(1, 1);
    SELECT * FROM t1 NATURAL JOIN t2;
    SELECT * FROM t1 JOIN t2 USING (j);
    4 Cột nối đơn kết quả
    a LEFT JOIN b USING (c1, c2, c3)
    8 được định nghĩa là
    CREATE TABLE t1 (i INT, j INT);
    CREATE TABLE t2 (k INT, j INT);
    INSERT INTO t1 VALUES(1, 1);
    INSERT INTO t2 VALUES(1, 1);
    SELECT * FROM t1 NATURAL JOIN t2;
    SELECT * FROM t1 JOIN t2 USING (j);
    6, trong đó:

    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    1

    Nếu thao tác tham gia là bất kỳ tham gia nào khác, các cột kết quả của nối bao gồm sự kết hợp của tất cả các cột của các bảng được nối.

    Hậu quả của định nghĩa của các cột kết hợp là, đối với các kết nối bên ngoài, cột kết hợp chứa giá trị của cột không phải -____ ____ 61 nếu một trong hai cột luôn luôn là

    a LEFT JOIN b USING (c1, c2, c3)
    1. Nếu cả hai cột là
    a LEFT JOIN b USING (c1, c2, c3)
    1, cả hai cột phổ biến đều có cùng giá trị, do đó, không quan trọng là giá trị nào là giá trị của cột kết hợp. Một cách đơn giản để giải thích điều này là xem xét rằng một cột kết hợp của một lần nối bên ngoài được biểu thị bằng cột chung của bảng bên trong của
    SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    5. Giả sử rằng các bảng
    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    01 và
    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    02 có nội dung sau:

    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    2

    Sau đó, đối với tham gia này, cột

    a LEFT JOIN b USING (c1, c2, c3)
    8 chứa các giá trị của
    CREATE TABLE t1 (i INT, j INT);
    CREATE TABLE t2 (k INT, j INT);
    INSERT INTO t1 VALUES(1, 1);
    INSERT INTO t2 VALUES(1, 1);
    SELECT * FROM t1 NATURAL JOIN t2;
    SELECT * FROM t1 JOIN t2 USING (j);
    3:

    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    3

    Ngược lại, đối với tham gia này, cột

    a LEFT JOIN b USING (c1, c2, c3)
    8 chứa các giá trị của
    CREATE TABLE t1 (i INT, j INT);
    CREATE TABLE t2 (k INT, j INT);
    INSERT INTO t1 VALUES(1, 1);
    INSERT INTO t2 VALUES(1, 1);
    SELECT * FROM t1 NATURAL JOIN t2;
    SELECT * FROM t1 JOIN t2 USING (j);
    4.

    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    4

    So sánh các kết quả đó với các truy vấn tương đương khác với

    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    07:

    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    5
    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    6
  • Một mệnh đề

    SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;
    9 có thể được viết lại dưới dạng mệnh đề
    SELECT t1.name, t2.salary
      FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;
    
    SELECT t1.name, t2.salary
      FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
    8 so sánh các cột tương ứng. Tuy nhiên, mặc dù
    SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;
    9 và
    SELECT t1.name, t2.salary
      FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;
    
    SELECT t1.name, t2.salary
      FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
    8 là tương tự nhau, nhưng chúng không hoàn toàn giống nhau. Hãy xem xét hai truy vấn sau:

    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    7

    Đối với việc xác định các hàng nào thỏa mãn điều kiện tham gia, cả hai tham gia đều giống hệt nhau về mặt ngữ nghĩa.

    Liên quan đến việc xác định cột nào sẽ hiển thị để mở rộng

    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    12, hai lần tham gia không giống nhau về mặt ngữ nghĩa. Tham gia
    SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;
    9 chọn giá trị kết hợp của các cột tương ứng, trong khi
    SELECT t1.name, t2.salary
      FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;
    
    SELECT t1.name, t2.salary
      FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
    8 tham gia chọn tất cả các cột từ tất cả các bảng. Đối với tham gia
    SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;
    9,
    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    12 chọn các giá trị này:

    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    8

    Đối với tham gia

    SELECT t1.name, t2.salary
      FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;
    
    SELECT t1.name, t2.salary
      FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
    8,
    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    18 chọn các giá trị này:

    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    9

    Với tham gia bên trong,

    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    19 giống như
    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    20 hoặc
    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    21 vì cả hai cột đều có cùng một giá trị. Với một tham gia bên ngoài (chẳng hạn như
    SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;
    1), một trong hai cột có thể là
    a LEFT JOIN b USING (c1, c2, c3)
    1. Cột đó bị bỏ qua từ kết quả.

  • Một mệnh đề

    SELECT t1.name, t2.salary
      FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;
    
    SELECT t1.name, t2.salary
      FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
    8 chỉ có thể đề cập đến các toán hạng của nó.

    Thí dụ:

    SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    0

    Câu lệnh không thành công với lỗi

    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    25 vì
    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    26 là một cột trong
    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    27, đây không phải là toán hạng của mệnh đề
    SELECT t1.name, t2.salary
      FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;
    
    SELECT t1.name, t2.salary
      FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
    8. Để cho phép kết nối được xử lý, hãy viết lại câu lệnh như sau:

    SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    1
  • SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    5 có mức độ ưu tiên cao hơn nhà điều hành dấu phẩy (
    SELECT * FROM (SELECT 1, 2, 3) AS t1;
    8), do đó biểu thức tham gia
    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    31 được hiểu là
    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    32, không phải là
    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    33. Điều này ảnh hưởng đến các câu lệnh sử dụng mệnh đề
    SELECT t1.name, t2.salary
      FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;
    
    SELECT t1.name, t2.salary
      FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
    8 vì điều khoản đó chỉ có thể đề cập đến các cột trong các toán hạng của tham gia và ưu tiên ảnh hưởng đến việc giải thích những toán hạng đó là gì.

    Thí dụ:

    SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    2

    SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    5 được ưu tiên hơn nhà điều hành dấu phẩy, do đó, các toán hạng cho mệnh đề
    SELECT t1.name, t2.salary
      FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;
    
    SELECT t1.name, t2.salary
      FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
    8 là
    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    37 và
    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    27.Vì
    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    39 không phải là một cột trong một trong hai toán hạng, kết quả là lỗi
    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                     ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
    40.

    Để cho phép kết nối được xử lý, hãy sử dụng một trong những chiến lược này:

    • Nhóm hai bảng đầu tiên một cách rõ ràng với dấu ngoặc đơn để các toán hạng cho mệnh đề

      SELECT t1.name, t2.salary
        FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;
      
      SELECT t1.name, t2.salary
        FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
      8 là
      SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                       ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
      42 và
      SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                       ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
      27:

      SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                       ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
      3
    • Tránh sử dụng toán tử dấu phẩy và sử dụng

      SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                       ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
      5 thay thế:

      SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                       ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
      4

    Giải thích ưu tiên tương tự cũng áp dụng cho các câu lệnh trộn toán tử dấu phẩy với

    SELECT left_tbl.*
        FROM { OJ left_tbl LEFT OUTER JOIN right_tbl
               ON left_tbl.id = right_tbl.id }
        WHERE right_tbl.id IS NULL;
    4,
    SELECT t1.name, t2.salary
      FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;
    
    SELECT t1.name, t2.salary
      FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
    9,
    SELECT left_tbl.*
        FROM { OJ left_tbl LEFT OUTER JOIN right_tbl
               ON left_tbl.id = right_tbl.id }
        WHERE right_tbl.id IS NULL;
    9 và
    SELECT left_tbl.*
        FROM { OJ left_tbl LEFT OUTER JOIN right_tbl
               ON left_tbl.id = right_tbl.id }
        WHERE right_tbl.id IS NULL;
    7, tất cả đều có ưu tiên cao hơn toán tử dấu phẩy.

  • Phần mở rộng MySQL so với tiêu chuẩn SQL: 2003 là MySQL cho phép bạn đủ điều kiện các cột chung (kết hợp) của

    SELECT * FROM table1, table2;
    
    SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id;
    
    SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id;
    
    SELECT * FROM table1 LEFT JOIN table2 USING (id);
    
    SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
      LEFT JOIN table3 ON table2.id = table3.id;
    8 hoặc
    SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;
    9 tham gia, trong khi tiêu chuẩn không cho phép điều đó.