使用EXISTS查找具有最大值的行

时间:2013-09-06 15:46:44

标签: sql sql-server

为什么我会在以下结果中重复Jim

CREATE TABLE #B (Name VARCHAR(10), Age INT)
INSERT INTO #B 
values 
('Jim', 21),
('Jim', 21),
('Jim', 19),
('Jim', 20),
('Nick', 20),
('Nick', 2),
('Nick', 20);


SELECT  DISTINCT
        Name,
        Age
FROM    #B A
WHERE   EXISTS
        (
        SELECT 1
        FROM #B B
        WHERE A.Age > B.Age
              AND A.NAME = B.NAME
        )

4 个答案:

答案 0 :(得分:3)

因为你有2行对应吗?

A.Age > B.Age and a.name = b.name

所以

Jim 20 > Jim 19
Jim 21 > Jim 19 
Jim 21 > Jim 20 

使用distinct,您得到Jim 20 and Jim 21(因为Jim 21合并为一个)

没有EXISTS的解决方案

select Name, Max(Age)
FROM #B
GROUP BY Name;

答案 1 :(得分:2)

正如SQL Fiddle显示的那样(here),您的查询没有按照您的想法执行。

除了获取max()之外,它取代除了最小值之外的所有内容。

此版本将获得max()

SELECT  DISTINCT
        Name,
        Age
FROM    B A
WHERE   NOT EXISTS
        (
        SELECT 1
        FROM B B
        WHERE A.Age < B.Age
              AND A.NAME = B.NAME
        );

答案 2 :(得分:2)

如果您使用的是SQL Server 2005及以上版本,那么使用下面描述的CTE将为您提供每个人的最大年龄:

drop table #B;
CREATE TABLE #B (Name![enter image description here][1] VARCHAR(10), Age INT)
INSERT INTO #B 
values 
('Jim', 21),
('Jim', 21),
('Jim', 19),
('Jim', 20),
('Nick', 20),
('Nick', 2),
('Nick', 20);

;with cte 
as (select Name, Age, ROW_NUMBER() over (PARTITION BY Name order by Name desc) as CNT
        from #B
        )
select Name, Age
from cte
where CNT = 1

enter image description here 结果:

答案 3 :(得分:1)

因为您告诉DBMS获取年龄低于一个人的最大年龄的所有行。

你获得了吉姆20和吉姆21的行。

如果你想要每个人的最大年龄,你必须:

SELECT distinct
    Name,
    Age
FROM    #B A
WHERE   not EXISTS
        (
        SELECT 1
        FROM #B B
        WHERE A.Age < B.Age
              AND A.NAME = B.NAME
        )

我在EXISTS之前添加了一个NOT。

保留DISTINCT,因为你有2行(吉姆,21岁),年龄相同