对此的替代查询(避免 DISTINCT)

All*_*nde 4 sql-server-2008 join query query-refactor

注意:我使用 MSSQL 2008,但我想它对许多其他数据库引擎有效 我有这个表“用户”:

用户 ID 用户国家 ID
1 用户 1 1
2 用户 2 2
3 用户 3 3
4 用户 4 4
5 用户 5 4
6 用户 6 3

而这张表“国家”

CountryID 国家
1 MX
2 美国
3 CAN
4 英格兰

如您所见,每个用户都属于一个国家。

如果我想知道,我在用户表上至少拥有一个用户的所有不同国家/地区,现在我执行以下查询:

select distinct country 
from Users inner join
countries on users.CountryID=countries.CountryID
Run Code Online (Sandbox Code Playgroud)

并实现下一个结果集:

能够
英国
MX
美国 

这确实是所有不同的国家,其中我在 muy 表 Users 上至少有一个用户。

我的疑问是,是否可以在不使用“DISTINCT”的情况下实现上述结果集,我的意思是只使用 JOINS 和条件?

这是 de DDL 脚本:

使用 [测试]
走
/****** 对象:表 [dbo].[用户] 脚本日期:09/21/2012 16:21:14 *****/
设置 ANSI_NULLS ON
走
设置 QUOTED_IDENTIFIER ON
走
创建表 [dbo].[用户](
    [用户ID] [int] NULL,
    [用户] [nvarchar](50) NULL,
    [CountryID] [int] NULL
) 在 [主要]
走
INSERT [dbo].[Users] ([UserID], [User], [CountryID]) VALUES (1, N'user 1', 1)
INSERT [dbo].[Users] ([UserID], [User], [CountryID]) VALUES (2, N'user 2', 2)
INSERT [dbo].[Users] ([UserID], [User], [CountryID]) VALUES (3, N'user 3', 3)
INSERT [dbo].[Users] ([UserID], [User], [CountryID]) VALUES (4, N'user 4', 4)
INSERT [dbo].[Users] ([UserID], [User], [CountryID]) VALUES (5, N'user 5', 4)
INSERT [dbo].[Users] ([UserID], [User], [CountryID]) VALUES (6, N'user 6', 3)
/****** 对象:表 [dbo].[Countries] 脚本日期:09/21/2012 16:21:14 *****/
设置 ANSI_NULLS ON
走
设置 QUOTED_IDENTIFIER ON
走
创建表 [dbo].[国家/地区](
    [CountryID] [int] NULL,
    [国家] [nvarchar](50) NULL
) 在 [主要]
走
INSERT [dbo].[Countries] ([CountryID], [Country]) VALUES (1, N'MX')
INSERT [dbo].[Countries] ([CountryID], [Country]) VALUES (2, N'USA')
INSERT [dbo].[Countries] ([CountryID], [Country]) VALUES (3, N'CAN')
INSERT [dbo].[Countries] ([CountryID], [Country]) VALUES (4, N'ENGLAND')
INSERT [dbo].[Countries] ([CountryID], [Country]) VALUES (5, N'BRAZIL')

RTh*_*mas 7

您可以使用以下内容获得相同的结果集:

select country from countries where exists 
    (select countryid from users 
        where users.countryid = country.countryid)
Run Code Online (Sandbox Code Playgroud)

或者

select country from countries where countryid in 
    (select countryid from users)
Run Code Online (Sandbox Code Playgroud)

这些都没有使用不同的但除此之外我不知道它们有多少“更好”。


Rob*_*ley 6

Rthomas 回答中的两个脚本都很有用。您还可以使用 GROUP BY,它与 RThomas 的方法具有相似的优势,但保持与原始查询相似的形式。

select country 
from Users inner join
countries on users.CountryID=countries.CountryID
GROUP BY countries.CountryID, countries.country;
Run Code Online (Sandbox Code Playgroud)

您按 CountryID 分组的原因是它是您的国家/地区表的主键,为查询优化器提供了一些更好的选择。

...除了它不在您的脚本中。

将 PK(带有聚集索引)放在您的表上,以及它们之间的 FK 关系。在用户表中索引 CountryID,并在 Country 字段上放置一个唯一索引。

完成所有这些后,使用 DISTINCT how you have 实际上将为您提供理想的执行计划。