GIỚI THIỆU THAM GIA VÀO mệnh đề WHERE


941

Để đơn giản, giả sử tất cả các lĩnh vực có liên quan là NOT NULL.

Bạn có thể làm:

SELECT
    table1.this, table2.that, table2.somethingelse
FROM
    table1, table2
WHERE
    table1.foreignkey = table2.primarykey
    AND (some other conditions)

Hoặc cái gì đó khác:

SELECT
    table1.this, table2.that, table2.somethingelse
FROM
    table1 INNER JOIN table2
    ON table1.foreignkey = table2.primarykey
WHERE
    (some other conditions)

Làm hai điều này trên cùng một cách trong MySQL?




18
Nếu tôi đã hiểu chính xác, biến thể đầu tiên là cú pháp ngầm định ANSI SQL-89 và biến thể thứ hai là cú pháp nối rõ ràng ANSI SQL-92. Cả hai sẽ dẫn đến cùng một kết quả trong việc tuân thủ các triển khai SQL và cả hai sẽ dẫn đến cùng một kế hoạch truy vấn trong các triển khai SQL được thực hiện tốt. Cá nhân tôi thích cú pháp SQL-89 nhưng nhiều người thích cú pháp SQL-92.
Mikko Rantalainen

11
@Hogan Tôi đã chỉ ra tên chính thức cho các cú pháp khác nhau. Không có câu trả lời nào đánh vần rõ ràng tên đầy đủ vì vậy tôi quyết định thêm chúng dưới dạng bình luận. Tuy nhiên, bình luận của tôi không trả lời được câu hỏi thực tế nên tôi đã thêm nó dưới dạng bình luận, không phải là câu trả lời. (Các câu trả lời được bình chọn cao có các khiếu nại như "INNER THAM GIA là cú pháp ANSI" và "cú pháp ẩn tham gia ANSI cũ hơn" không nói gì cả vì cả hai cú pháp đều là các cú pháp ANSI khác nhau.)
Mikko Rantalainen

Câu trả lời:


710

INNER JOIN là cú pháp ANSI mà bạn nên sử dụng.

Nó thường được coi là dễ đọc hơn, đặc biệt là khi bạn tham gia nhiều bảng.

Nó cũng có thể dễ dàng thay thế bằng một OUTER JOIN bất cứ khi nào có nhu cầu.

Các WHERE cú pháp được mô hình quan hệ nhiều hướng.

Kết quả của hai bảng JOIN ed là một sản phẩm cartesian của các bảng mà bộ lọc được áp dụng, chỉ chọn những hàng có khớp cột.

Dễ dàng nhận thấy điều này với WHERECú pháp cú pháp.

Ví dụ của bạn, trong MySQL (và trong SQL nói chung) hai truy vấn này là từ đồng nghĩa.

Cũng lưu ý rằng MySQL cũng có một STRAIGHT_JOIN điều khoản.

Sử dụng mệnh đề này, bạn có thể kiểm soát JOIN thứ tự: bảng nào được quét ở vòng ngoài và bảng nào ở vòng trong.

Bạn không thể kiểm soát điều này trong MySQL bằng WHEREcú pháp.


10
Cảm ơn, Quassnoi. Bạn đã có rất nhiều chi tiết trong ans của bạn; có công bằng không khi nói rằng "có, những truy vấn đó là tương đương, nhưng bạn nên sử dụng kết nối bên trong vì nó dễ đọc hơn và dễ sửa đổi hơn"?
mã allyour

8
@allyourcode: cho Oracle, SQL Server, MySQLPostgreSQL- vâng. Đối với các hệ thống khác, có lẽ cũng vậy, nhưng bạn nên kiểm tra tốt hơn.
Quassnoi

13
FWIW, sử dụng dấu phẩy với các điều kiện nối trong WHEREmệnh đề cũng nằm trong tiêu chuẩn ANSI.
Bill Karwin

1
@Bill Karwin: JOINtừ khóa không phải là một phần của tiêu chuẩn độc quyền cho đến gần đây có vẻ như gần đây. Nó đi vào Oraclechỉ trong phiên bản 9và thành PostgreSQLphiên bản 7.2(cả hai được phát hành trong 2001). Sự xuất hiện của từ khóa này là một phần của ANSIviệc áp dụng tiêu chuẩn và đó là lý do tại sao từ khóa này thường được liên kết với ANSI, mặc dù thực tế sau này cũng hỗ trợ dấu phẩy như một từ đồng nghĩa CROSS JOIN.
Quassnoi

9
Tuy nhiên, ANSI SQL-89 được chỉ định tham gia được thực hiện bằng dấu phẩy và điều kiện trong một WHEREmệnh đề (không có điều kiện, phép nối tương đương với phép nối chéo, như bạn đã nói). ANSI SQL-92 đã thêm JOINtừ khóa và cú pháp liên quan, nhưng cú pháp kiểu dấu phẩy vẫn được hỗ trợ cho tính tương thích ngược.
Bill Karwin

182

Những người khác đã chỉ ra rằng INNER JOINgiúp con người dễ đọc, và đó là ưu tiên hàng đầu, tôi đồng ý.
Hãy để tôi cố gắng giải thích tại sao cú pháp tham gia dễ đọc hơn.

Một SELECTtruy vấn cơ bản là:

SELECT stuff
FROM tables
WHERE conditions

Điều SELECTkhoản cho chúng ta biết những gì chúng ta sẽ nhận lại; cácFROM khoản cho chúng ta biết nơi chúng tôi đang nhận được nó từ đâu, và các WHEREkhoản cho chúng ta biết những người chúng tôi đang nhận được.

JOIN là một tuyên bố về các bảng, làm thế nào chúng được liên kết với nhau (về mặt khái niệm, thực sự, vào một bảng duy nhất).

Bất kỳ yếu tố truy vấn nào kiểm soát các bảng - nơi chúng tôi nhận được nội dung - về mặt ngữ nghĩa thuộc về FROMmệnh đề (và tất nhiên, đó là nơi JOINcác yếu tố đi). Việc đưa các phần tử tham gia vào WHEREmệnh đề sẽ kết hợp giữa cái nàotừ đâu , đó là lý do tại sao JOINcú pháp được ưa thích.


7
Cảm ơn đã làm rõ lý do tại sao tham gia bên trong được ưa thích Carl. Tôi nghĩ rằng ans của bạn đã tiềm ẩn trong những người khác, nhưng rõ ràng thường tốt hơn (vâng, tôi là một người hâm mộ Python).
mã allyour

2
Các ngữ nghĩa của BẬT và Ở ĐÂU có nghĩa là đối với THAM GIA sau lần THAM GIA cuối cùng , việc bạn sử dụng không thành vấn đề . Mặc dù bạn mô tả BẬT là một phần của THAM GIA, nó cũng là một bộ lọc sau một sản phẩm của Cartesian. Cả ON và WHERE đều lọc một sản phẩm của Cartesian. Nhưng phải BẬT hoặc chọn phụ với WHERE phải được sử dụng trước THAM GIA NGOÀI cuối cùng. (JOIN không phải là "trên" cặp cột Bất kỳ hai bảng có thể được ghép điều kiện nào đó chỉ là một cách để giải thích câu lệnh JOIN ON bình đẳng của cột cụ thể...)
philipxy

Ngay cả khi bạn đang sử dụng WHERE cho cùng hiệu ứng của INNER THAM GIA, bạn sẽ đề cập đến hai bảng của mình trong phần TỪ của truy vấn. Vì vậy, về cơ bản, bạn vẫn đang ám chỉ nơi bạn đang lấy dữ liệu của mình trong mệnh đề TỪ, vì vậy tôi đoán bạn không thể nói nó nhất thiết phải "kết hợp giữa cái nào và từ đâu"
cybergeek654

@ArsenKhachaturyan Chỉ vì một từ khóa hoặc mã định danh được sử dụng trong văn bản không có nghĩa đó là mã & cần định dạng mã. Đó là một lựa chọn định dạng có thể đi theo bất kỳ cách nào và nếu nó hợp lý để chỉnh sửa ở đây thì điều hợp lý là mọi bài đăng sẽ liên tục được chỉnh sửa sang định dạng khác - điều đó có nghĩa là nó không chính đáng. (Cộng với định dạng mã mỗi từ nội tuyến có thể khó đọc.) Tương tự cho các đoạn ngắt đoạn ở đây - chúng không đặc biệt làm rõ. Tương tự với 'mà' so với 'đó'. Và tên của các ngôn ngữ lập trình không nên ở định dạng mã. PS Bạn đã thêm một lỗi ngắt dòng.
philipxy

@philipxy như bạn đã đề cập "không có nghĩa là ...", nhưng rõ ràng điều đó không có nghĩa là nó không thể được đánh dấu bằng từ khóa mã. Có, đó là lựa chọn được thực hiện nhưng rất nhiều bài viết được thực hiện mà không biết thực tế đó. Do đó quyết định của tôi để thực hiện các thay đổi không nhằm mục đích phá vỡ bất cứ điều gì nhưng làm cho nó dễ đọc hơn. Nếu bạn nhận thấy bất kỳ sự phá vỡ nào sau khi hình thành các thay đổi, xin lỗi vì điều đó và rõ ràng bạn có thể hoàn nguyên các thay đổi đó.
Asen Khachaturyan

143

Áp dụng các câu điều kiện trong ON / WHERE

Ở đây tôi đã giải thích về các bước xử lý truy vấn logic.


Tham khảo: Bên trong Microsoft® SQL Server ™ 2005
Nhà xuất bản truy vấn T-SQL : Microsoft Press
Pub Ngày: 07 tháng 3 năm 2006
In ISBN-10: 0-7356-2313-9
In ISBN-13: 980-0-7356-2313-2
Trang: 640

Bên trong Microsoft® SQL Server ™ 2005 Truy vấn T-SQL

(8)  SELECT (9) DISTINCT (11) TOP <top_specification> <select_list>
(1)  FROM <left_table>
(3)       <join_type> JOIN <right_table>
(2)       ON <join_condition>
(4)  WHERE <where_condition>
(5)  GROUP BY <group_by_list>
(6)  WITH {CUBE | ROLLUP}
(7)  HAVING <having_condition>
(10) ORDER BY <order_by_list>

Khía cạnh đáng chú ý đầu tiên của SQL khác với các ngôn ngữ lập trình khác là thứ tự xử lý mã. Trong hầu hết các ngôn ngữ lập trình, mã được xử lý theo thứ tự được viết. Trong SQL, mệnh đề đầu tiên được xử lý là mệnh đề TỪ, trong khi mệnh đề SELECT, xuất hiện đầu tiên, được xử lý gần như cuối cùng.

Mỗi bước tạo một bảng ảo được sử dụng làm đầu vào cho bước sau. Các bảng ảo này không có sẵn cho người gọi (ứng dụng khách hoặc truy vấn bên ngoài). Chỉ bảng được tạo bởi bước cuối cùng được trả về cho người gọi. Nếu một mệnh đề nhất định không được chỉ định trong truy vấn, bước tương ứng chỉ đơn giản là bỏ qua.

Mô tả ngắn gọn về các giai đoạn xử lý truy vấn logic

Đừng quá lo lắng nếu việc mô tả các bước dường như không có ý nghĩa gì cho đến bây giờ. Chúng được cung cấp như một tài liệu tham khảo. Các phần xuất hiện sau ví dụ kịch bản sẽ bao gồm các bước chi tiết hơn nhiều.

  1. TỪ: Một sản phẩm của Cartesian (nối chéo) được thực hiện giữa hai bảng đầu tiên trong mệnh đề TỪ và kết quả là bảng ảo VT1 được tạo.

  2. ON: Bộ lọc ON được áp dụng cho VT1. Chỉ các hàng có <join_condition>TRUE được chèn vào VT2.

  3. OUTER (tham gia): Nếu một OUTER THAM GIA được chỉ định (trái ngược với CROSS THAM GIA hoặc INNER THAM GIA), các hàng từ bảng được bảo tồn hoặc các bảng không tìm thấy kết quả khớp được thêm vào các hàng từ VT2 dưới dạng các hàng ngoài, tạo ra VT3. Nếu có nhiều hơn hai bảng xuất hiện trong mệnh đề TỪ, các bước từ 1 đến 3 được áp dụng lặp đi lặp lại giữa kết quả của lần nối cuối cùng và bảng tiếp theo trong mệnh đề TỪ cho đến khi tất cả các bảng được xử lý.

  4. WHERE: Bộ lọc WHERE được áp dụng cho VT3. Chỉ các hàng có <where_condition>TRUE được chèn vào VT4.

  5. NHÓM THEO: Các hàng từ VT4 được sắp xếp theo nhóm dựa trên danh sách cột được chỉ định trong mệnh đề GROUP BY. VT5 được tạo ra.

  6. CUBE | ROLLUP: Siêu nhóm (nhóm các nhóm) được thêm vào các hàng từ VT5, tạo VT6.

  7. HAVING: Bộ lọc HAVING được áp dụng cho VT6. Chỉ các nhóm có <having_condition>TRUE được chèn vào VT7.

  8. CHỌN: Danh sách CHỌN được xử lý, tạo VT8.

  9. DISTINCT: Các hàng trùng lặp được xóa khỏi VT8. VT9 được tạo ra.

  10. ORDER BY: Các hàng từ VT9 được sắp xếp theo danh sách cột được chỉ định trong mệnh đề ORDER BY. Một con trỏ được tạo ra (VC10).

  11. TOP: Số lượng hoặc tỷ lệ phần trăm của các hàng được chỉ định từ đầu VC10. Bảng VT11 được tạo và trả lại cho người gọi.



Do đó, (INNER THAM GIA) BẬT sẽ lọc dữ liệu (số lượng dữ liệu của VT sẽ bị giảm ở đây) trước khi áp dụng mệnh đề WHERE. Các điều kiện nối tiếp theo sẽ được thực hiện với dữ liệu được lọc giúp cải thiện hiệu suất. Sau đó, chỉ điều kiện WHERE sẽ áp dụng điều kiện lọc.

(Áp dụng các câu lệnh có điều kiện trong ON / WHERE sẽ không tạo ra nhiều khác biệt trong một số trường hợp. Điều này phụ thuộc vào số lượng bảng bạn đã tham gia và số lượng hàng có sẵn trong mỗi bảng tham gia)


10
"Do đó, (INNER THAM GIA) BẬT sẽ lọc dữ liệu (Số lượng dữ liệu của VT sẽ bị giảm ở đây) trước khi áp dụng mệnh đề WHERE." Không cần thiết. Bài viết là về thứ tự hợp lý của xử lý. Khi bạn nói một triển khai cụ thể sẽ làm một việc trước một điều khác, bạn đang nói về thứ tự xử lý được thực hiện . Việc triển khai được phép thực hiện bất kỳ tối ưu hóa nào họ muốn, miễn là kết quả giống như khi việc triển khai tuân theo thứ tự logic. Joe Celko đã viết rất nhiều về điều này trên Usenet.
Mike Sherrill 'Nhớ lại mèo'

@rafidheen "(INNER THAM GIA) ON sẽ lọc dữ liệu ... trước khi áp dụng mệnh đề WHERE ... giúp cải thiện hiệu suất." Điểm tốt. "Sau đó, chỉ điều kiện WHERE sẽ áp dụng điều kiện lọc" Điều khoản HAVING thì sao?
James

@James Yêu cầu đó của rafidheen là sai. Xem 'tham gia tối ưu hóa' trong hướng dẫn. Ngoài ra ý kiến ​​khác của tôi trên trang này. (Và MikeSherrill'CatRecall''s.) Những mô tả "hợp lý" như vậy mô tả giá trị kết quả, chứ không phải cách tính toán thực sự. Và hành vi thực hiện như vậy không được đảm bảo để không thay đổi.
philipxy

67

Cú pháp tham gia ngầm định ANSI cũ hơn, ít rõ ràng hơn và không được đề xuất.

Ngoài ra, đại số quan hệ cho phép khả năng hoán đổi của các vị từ trong WHEREmệnh đề và INNER JOIN, do đó, ngay cả INNER JOINcác truy vấn vớiWHERE mệnh đề cũng có thể có các vị từ được sắp xếp lại bởi trình tối ưu hóa.

Tôi khuyên bạn nên viết các truy vấn theo cách dễ đọc nhất có thể.

Đôi khi điều này bao gồm làm cho INNER JOINtương đối "không đầy đủ" và đưa một số tiêu chí vàoWHERE cách đơn giản để làm cho danh sách các tiêu chí lọc dễ dàng duy trì hơn.

Ví dụ: thay vì:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
    AND c.State = 'NY'
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
    AND a.Status = 1

Viết:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
WHERE c.State = 'NY'
    AND a.Status = 1

Nhưng nó phụ thuộc, tất nhiên.


16
Đoạn đầu tiên của bạn chắc chắn làm tổn thương não tôi nhiều hơn. Có ai thực sự làm điều đó? Nếu tôi gặp một người làm điều đó, tôi có thể đánh anh ta qua đầu không?
mã allyour

3
Tôi định vị các tiêu chí nơi nó có ý nghĩa nhất. Nếu tôi tham gia vào bảng tra cứu ảnh chụp nhanh nhất quán theo thời gian (và tôi không có chế độ xem hoặc UDF thực thi việc chọn ngày hợp lệ), tôi sẽ bao gồm ngày hiệu lực trong tham gia và không phải trong WHERE vì nó ít hơn có khả năng vô tình bị loại bỏ.
Cade Roux

14
@allyourcode: mặc dù rất hiếm khi thấy loại cú pháp tham gia này trong INNER THAM GIA, nhưng nó khá phổ biến đối với RIGHT THAM GIA và TRÁI PHIẾU - chỉ định chi tiết hơn trong vị từ tham gia loại bỏ sự cần thiết của truy vấn phụ và ngăn chặn các liên kết bên ngoài của bạn vô tình bị biến vào THAM GIA. (Mặc dù tôi đồng ý rằng với INNER THAM GIA, tôi hầu như luôn đặt c.State = 'NY' trong mệnh đề WHERE)
Dave Markle

1
@allyourcode Tôi chắc chắn làm được điều đó! Và tôi đồng ý với Cade .. Tôi tò mò liệu có lý do chính đáng nào không
Arth

31

Các phép nối ngầm định (đó là những gì truy vấn đầu tiên của bạn được biết đến) trở nên khó hiểu hơn, khó đọc và khó duy trì hơn một khi bạn cần bắt đầu thêm nhiều bảng vào truy vấn của mình. Hãy tưởng tượng thực hiện cùng một truy vấn và loại tham gia trên bốn hoặc năm bảng khác nhau ... đó là một cơn ác mộng.

Sử dụng một phép nối rõ ràng (ví dụ thứ hai của bạn) sẽ dễ đọc hơn và dễ bảo trì hơn.


48
Tôi không thể không đồng ý nhiều hơn. Cú pháp THAM GIA cực kỳ dài dòng và khó tổ chức. Tôi có rất nhiều truy vấn tham gia 5, 10, thậm chí 15 bảng bằng cách sử dụng mệnh đề WHERE tham gia và chúng hoàn toàn có thể đọc được. Viết lại một truy vấn như vậy bằng cú pháp THAM GIA dẫn đến một mớ hỗn độn bị cắt xén. Điều này chỉ cho thấy không có câu trả lời đúng cho câu hỏi này và nó phụ thuộc nhiều hơn vào những gì bạn cảm thấy thoải mái.

33
Nô-ê, tôi nghĩ bạn có thể là thiểu số ở đây.
matt b

2
Tôi được +1 cho matt và Noah. Tôi thích sự đa dạng :). Tôi có thể thấy Nô-ê đến từ đâu; tham gia bên trong không thêm bất cứ điều gì mới vào ngôn ngữ, và chắc chắn là dài dòng hơn. Mặt khác, nó có thể làm cho tình trạng 'nơi' của bạn ngắn hơn nhiều, điều này thường có nghĩa là nó dễ đọc hơn.
mã allyour

5
Tôi sẽ giả định rằng bất kỳ DBMS lành mạnh nào cũng sẽ dịch hai truy vấn vào cùng một kế hoạch thực hiện; tuy nhiên trong thực tế, mỗi DBMS là khác nhau và cách duy nhất để biết chắc chắn là thực sự kiểm tra kế hoạch thực hiện (nghĩa là bạn sẽ phải tự kiểm tra nó).
matt b

Có đúng như @rafidheen đã đề xuất trong một câu trả lời khác (câu trả lời với chuỗi thực thi SQL chi tiết) rằng các THAM GIA được lọc cùng một lúc, giảm kích thước của các tham gia tham gia khi so sánh với tham gia cartesian đầy đủ từ 3 bảng trở lên, với bộ lọc WHERE đang được áp dụng hồi tố? Nếu vậy, nó sẽ đề nghị THAM GIA cung cấp cải tiến hiệu suất (cũng như các lợi thế khi tham gia trái / phải, cũng như chỉ ra một câu trả lời khác).
James

26

Tôi cũng sẽ chỉ ra rằng việc sử dụng cú pháp cũ có nhiều lỗi hơn. Nếu bạn sử dụng các phép nối bên trong mà không có mệnh đề ON, bạn sẽ gặp lỗi cú pháp. Nếu bạn sử dụng cú pháp cũ hơn và quên một trong các điều kiện nối trong mệnh đề where, bạn sẽ nhận được một phép nối chéo. Các nhà phát triển thường khắc phục điều này bằng cách thêm từ khóa riêng biệt (thay vì sửa lỗi liên kết vì họ vẫn không nhận ra chính liên kết bị hỏng) có thể khắc phục sự cố, nhưng sẽ làm chậm đáng kể truy vấn.

Ngoài ra để bảo trì nếu bạn có một tham gia chéo trong cú pháp cũ, làm thế nào để người bảo trì biết nếu bạn muốn có một (có những tình huống cần tham gia chéo) hoặc nếu đó là một tai nạn cần được khắc phục?

Hãy để tôi chỉ cho bạn câu hỏi này để xem tại sao cú pháp ngầm là xấu nếu bạn sử dụng các phép nối trái. Sybase * = to Ansi Standard với 2 bảng bên ngoài khác nhau cho cùng một bảng bên trong

Thêm vào đó (câu chuyện cá nhân ở đây), tiêu chuẩn sử dụng các phép nối rõ ràng đã hơn 20 năm, điều đó có nghĩa là cú pháp nối ngầm đã bị lỗi thời trong 20 năm đó. Bạn có thể viết mã ứng dụng bằng cú pháp đã lỗi thời trong 20 năm không? Tại sao bạn muốn viết mã cơ sở dữ liệu?


3
@HLGEM: Mặc dù tôi hoàn toàn đồng ý rằng THAM GIA rõ ràng là tốt hơn, có những trường hợp khi bạn chỉ cần sử dụng cú pháp cũ. Một ví dụ trong thế giới thực: ANSI THAM GIA chỉ vào Oracle trong phiên bản 9i được phát hành năm 2001 và cho đến chỉ một năm trước (16 năm kể từ khi tiêu chuẩn được công bố) tôi đã phải hỗ trợ một loạt các cài đặt 8i mà chúng tôi đã có để phát hành bản cập nhật quan trọng. Tôi không muốn duy trì hai bộ cập nhật, vì vậy chúng tôi đã phát triển và thử nghiệm các bản cập nhật đối với tất cả các cơ sở dữ liệu bao gồm 8i, điều đó có nghĩa là chúng tôi không thể sử dụng ANSI THAM GIA.
Quassnoi

+1 điểm thú vị khi bạn chỉ ra rằng sintax không có INNER THAM GIA dễ bị lỗi hơn. Tôi bối rối về câu cuối cùng của bạn khi bạn nói "... tiêu chuẩn sử dụng các phép nối rõ ràng là 17 tuổi." Vì vậy, sau đó bạn có đề xuất sử dụng từ khóa INNER THAM GIA hay không?
Marco Demaio

1
@Marco Demaio, có, luôn luôn sử dụng INNER THAM GIA hoặc THAM GIA (hai cái này giống nhau) hoặc LEFT THAM GIA hoặc RIGHT THAM GIA hoặc CROSS THAM GIA và không bao giờ sử dụng dấu phẩy ngầm.
HLGEM

2
"Tại sao bạn muốn viết mã cơ sở dữ liệu [20 tuổi]?" - Tôi nhận thấy bạn viết SQL bằng cách sử dụng HAVING"lỗi thời" kể từ khi SQL bắt đầu hỗ trợ các bảng dẫn xuất. Tôi cũng nhận thấy rằng bạn không sử dụng NATURAL JOINmặc dù tôi sẽ cho rằng nó đã làm INNER JOIN'lỗi thời'. Vâng, bạn có lý do của bạn (không cần phải nêu lại ở đây!): Quan điểm của tôi là, những người thích sử dụng cú pháp cũ cũng có lý do của họ và độ tuổi tương đối của cú pháp là rất ít nếu có liên quan.
onedaywhen

1
WHERE vẫn ở trong tiêu chuẩn (chỉ cho tôi biết nơi nào không). Vì vậy, không có gì lỗi thời, rõ ràng. Ngoài ra, "thay vì sửa lỗi tham gia" cho tôi thấy một nhà phát triển nên tránh xa DBMS nói chung, ở rất xa.
Jürgen A. Erhard

12

Chúng có một ý nghĩa khác nhau có thể đọc được của con người.

Tuy nhiên, tùy thuộc vào trình tối ưu hóa truy vấn, chúng có thể có cùng ý nghĩa với máy.

Bạn nên luôn luôn mã để có thể đọc được.

Điều đó có nghĩa là, nếu đây là mối quan hệ tích hợp, hãy sử dụng phép nối rõ ràng. nếu bạn khớp với dữ liệu liên quan yếu, hãy sử dụng mệnh đề where.


11

Tiêu chuẩn SQL: 2003 đã thay đổi một số quy tắc ưu tiên để câu lệnh THAM GIA được ưu tiên so với phép nối "dấu phẩy". Điều này thực sự có thể thay đổi kết quả truy vấn của bạn tùy thuộc vào cách thiết lập. Điều này gây ra một số vấn đề cho một số người khi MySQL 5.0.12 chuyển sang tuân thủ tiêu chuẩn.

Vì vậy, trong ví dụ của bạn, các truy vấn của bạn sẽ hoạt động như nhau. Nhưng nếu bạn đã thêm bảng thứ ba: CHỌN ... TỪ bảng1, bảng2 THAM GIA bảng3 TRÊN ... Ở ĐÂU ...

Trước MySQL 5.0.12, bảng1 và bảng2 sẽ được nối trước, sau đó đến bảng 3. Bây giờ (5.0.12 trở đi), bảng2 và bảng3 được nối trước, sau đó đến bảng1. Nó không luôn luôn thay đổi kết quả, nhưng nó có thể và bạn thậm chí có thể không nhận ra nó.

Tôi không bao giờ sử dụng cú pháp "dấu phẩy" nữa, chọn ví dụ thứ hai của bạn. Dù sao nó cũng dễ đọc hơn rất nhiều, các điều kiện THAM GIA với các THAM GIA, không được tách thành một phần truy vấn riêng.


SQL chuẩn không thay đổi. MySQL đã sai và bây giờ là đúng. Xem hướng dẫn sử dụng MySQL.
philipxy

4

Tôi biết bạn đang nói về MySQL, nhưng dù sao: Trong Oracle 9, các phép nối rõ ràng và các phép nối ngầm sẽ tạo ra các kế hoạch thực hiện khác nhau. AFAIK đã được giải quyết trong Oracle 10+: không còn sự khác biệt như vậy nữa.


1

Cú pháp tham gia ANSI chắc chắn là dễ mang theo hơn.

Tôi đang tiến hành nâng cấp Microsoft SQL Server và tôi cũng sẽ đề cập rằng cú pháp = * và * = cho các phép nối ngoài trong SQL Server không được hỗ trợ (không có chế độ tương thích) cho máy chủ sql 2005 và sau đó.


2
Ngay cả trong SQL Server 2000, = và = có thể cho kết quả sai và không bao giờ được sử dụng.
HLGEM

2
*==*chưa bao giờ là ANSI và chưa bao giờ là một ký hiệu tốt. Đó là lý do tại sao ON là cần thiết - đối với OUTER THAM GIA trong trường hợp không có subselect (được thêm vào cùng một lúc, vì vậy chúng không thực sự cần thiết trong CROSS & INNER
THAM GIA

1

Nếu bạn thường lập trình các thủ tục lưu trữ động, bạn sẽ yêu ví dụ thứ hai của mình (sử dụng ở đâu). Nếu bạn có nhiều thông số đầu vào khác nhau và nhiều mớ hỗn độn, thì đó là cách duy nhất. Nếu không, cả hai sẽ chạy cùng một kế hoạch truy vấn nên chắc chắn không có sự khác biệt rõ ràng trong các truy vấn cổ điển.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.