SQL的DISTINCT子句如何工作?

kor*_*iow 8 sql join distinct sql-server-2008

我正在寻找关于DISTINCT子句如何在SQL中运行的答案(SQL Server 2008,如果这有所不同)对多个表连接的查询?

我的意思是SQL引擎如何使用DISTINCT子句处理查询?

我问的原因是我的经验丰富的同事告诉我,SQL将DISTINCT应用于每个表的每个字段.对我来说似乎不太可能,但我想确保....

例如,有两个表:

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) 
)
Run Code Online (Sandbox Code Playgroud)

然后有这个查询:

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 
Run Code Online (Sandbox Code Playgroud)

假设有两个角色的用户,则上述查询将返回具有相同用户名的两个记录.

但这个查询具有明显的:

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 
Run Code Online (Sandbox Code Playgroud)

将只返回一个用户名.

问题是SQL是否会比较所有连接表中的所有字段(u_id,u_name,u_password,r_id,r_name),还是只比较查询中的命名字段(u_name)并区分结果?

JNK*_*JNK 19

DISTINCT过滤掉返回字段的重复值.

一个非常简单的方法来看待它:

  • 它根据您的FROMWHERE子句构建您的整体结果集(包括重复项)
  • 它根据您要返回的字段对结果集进行排序
  • 它会删除这些字段中的任何重复值

它在语义上等同于GROUP BY所有返回字段都在GROUP BY子句中的位置.