假设我有这些数据:
create table People (ID int identity, Name nvarchar(50), Age int);
insert into People values
('Bill Jones', 50),
('Bill Jones', 12),
('Sam Smith', 23),
('Jill Brown', 44),
('Jill Brown', 67),
('Jill Brown', 3)
这个查询:
select * from (
select
ID, Name, Age,
row_number() over (partition by Name order by ID) [rownum]
from People
) a where [rownum] = 1
每个唯一名称成功返回一个人。
ID NAME AGE ROWNUM
1 Bill Jones 50 1
4 Jill Brown 44 1
3 Sam Smith 23 1
但是,为了使用row_number()
,我必须指定order by
,导致查询计划包含昂贵的排序操作。
我不关心返回哪个的人;我每个名字只需要一个人。
有没有办法在没有排序的情况下做到这一点?
您可以在此处查看我的查询和执行计划:http://sqlfiddle.com/#!3/3ee32/1/0
答案 0 :(得分:2)
我不知道它是否优化了但它显示了你想要的记录......没有订单条款/.....
Select * from People a where id in (Select Top(1) id from people b where name in
(Select name from people group by name) and a.name=b.name)
答案 1 :(得分:1)
查询怎么样:
select
distinct Name,
(Select top 1 Age from People b where b.Name=a.Name) Age
from People a
OR
select b.* From(
select min(ID) ID from people group by Name
) a inner join People b on a.ID=b.ID
包含所有列。 事实:这些查询都没有超过ROW_NUMBER()的查询!
答案 2 :(得分:1)
您可以考虑以下问题:
SELECT
a.*
FROM
People a
LEFT JOIN
People b
ON
(a.Name = b.Name AND a.id > b.id)
WHERE b.id IS NULL
当我在SQLFiddle中运行它时,它似乎表现得更好:
原始查询:0.0146747
自我加入:0.0071784
答案 3 :(得分:1)
我实际上看到了编写原始查询的不同方法。您还可以考虑使用Common Table Expression
。虽然我相信优化水平几乎相同。我确实更喜欢CTE
。
with cte
as
(
select ID, Name, Age,
row_number() over (partition by Name order by ID) [rownum]
from People
)
select *
from cte
where [rownum] = 1