2012-01-24 30 views
7

Tôi đang tìm câu trả lời về cách mệnh đề DISTINCT hoạt động trong SQL (SQL Server 2008 nếu điều đó tạo ra sự khác biệt) trên một truy vấn với nhiều bảng được nối với nhau như thế nào?Điều khoản DISTINCT của SQL hoạt động như thế nào?

Tôi có nghĩa là cách công cụ SQL xử lý truy vấn bằng mệnh đề DISTINCT?

Lý do tôi hỏi là tôi đã được đồng nghiệp nhiều kinh nghiệm của tôi kể rằng SQL áp dụng DISTINCT cho mọi lĩnh vực của mỗi bảng. Nó có vẻ như không đối với tôi, nhưng tôi muốn chắc chắn ....

Ví dụ có hai bảng:

CREATE TABLE users 
(
u_id INT PRIMARY KEY, 
u_name VARCHAR(30), 
u_password VARCHAR(30) 
) 

CREATE TABLE roles 
(
r_id INT PRIMARY KEY, 
r_name VARCHAR(30) 
) 

CREATE TABLE users_l_roles 
(
u_id INT FOREIGN KEY REFERENCES users(u_id) , 
r_id INT FOREIGN KEY REFERENCES roles(r_id) 
) 

Và sau đó có truy vấn này:

SELECT   u_name 
FROM   users 
INNER JOIN  users_l_roles ON users.u_id = users_l_roles.u_id 
INNER JOIN  roles ON users_l_roles.r_id = roles.r_id 

Giả sử có người dùng với hai vai trò thì truy vấn trên sẽ trả về hai bản ghi có cùng tên người dùng.

Nhưng truy vấn này với riêng biệt:

SELECT DISTINCT u_name 
FROM   users 
INNER JOIN  users_l_roles ON users.u_id = users_l_roles.u_id 
INNER JOIN  roles ON users_l_roles.r_id = roles.r_id 

sẽ trở lại chỉ có một tên người dùng.

Câu hỏi đặt ra là liệu SQL sẽ so sánh tất cả các trường từ tất cả các bảng được nối (u_id, u_name, u_password, r_id, r_name) hay nó sẽ chỉ so sánh các trường được đặt tên trong truy vấn (u_name) và phân biệt kết quả?

+0

bạn rùng mình kiểm tra kế hoạch giải thích về cách công cụ SQL của bạn quyết định xử lý cú pháp của bạn. – Randy

Trả lời

13

DISTINCT lọc ra các giá trị trùng lặp của các trường trả lại của bạn.

Một cách thực sự đơn giản để nhìn vào nó là:

  • Nó xây dựng tập kết quả tổng thể của bạn (bao gồm cả bản sao) dựa trên FROMWHERE bạn khoản
  • Nó phân loại mà tập kết quả dựa trên các trường bạn muốn trở lại
  • Nó loại bỏ bất kỳ giá trị trùng lặp trong các lĩnh vực này

Đó là ngữ nghĩa tương đương với một GROUP BY trong đó tất cả các trường được trả về nằm trong mệnh đề GROUP BY.

+1

Tôi đã học được tất cả điều này bằng cách thực hiện ngay bây giờ, bằng cách thực hiện một sai lầm như được hiển thị ở đây - http://stackoverflow.com/questions/20750181/count-with-distinct Cuối cùng, tôi đã kết thúc bằng cách sử dụng GROUP BY thay vì DISTINCT. – Steam

3

DISTINCT chỉ cần hủy trùng lặp bản ghi kết quả sau khi tất cả các hoạt động truy vấn khác đã được thực hiện. This article có nhiều chi tiết hơn.

0

Đầu tiên chọn tất cả 'các bản ghi có sẵn' và sau đó, nó sẽ xóa các bản ghi trùng lặp trong tất cả các bản ghi có sẵn và các bản in.

Các vấn đề liên quan