Sql 使用EXISTS查找具有最大值的行
为什么我在下面的结果中得到了Jim的重复Sql 使用EXISTS查找具有最大值的行,sql,sql-server,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 EX
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
)
因为您已经告诉DBMS获取年龄低于一个人的最大年龄的所有行 您为Jim 20和Jim 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
)
我添加了一个以前不存在的
保持不同,因为您有两行Jim,21岁,年龄相同因为您有两行对应
A.Age > B.Age and a.name = b.name
所以
使用distinct,当Jim 21合并为一个时,您将得到Jim 20和Jim 21
不存在的解决方案
正如SQLFiddle所显示的,您的查询并没有按照您认为的那样进行
它不是获取最大值,而是获取除最小值以外的所有值
此版本将获得最大值:
如果您使用的是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
结果:您希望看到什么?读到这个问题,看起来合乎逻辑的是,你会得到Jim两次。@AdrianWragg-好的,我现在明白了:只要同一个名字的年龄较低,那么该行就会返回,也就是说,它排除了每个名字的年龄最小的行。+1谢谢-我知道这个替代方法-但是如果我在OP中从查询中去掉DISTINCT,那么它可以做一些简单查询无法完成的事情例如,如果不添加子查询,则无法执行此操作。因此,为什么我想在使用EXISTS时获得正确的逻辑。@RaphaëlAlthaus…实际上,我想知道EXISTS不起作用的原因-我对寻找替代方案不感兴趣。@kin+1提出这个问题
select Name, Max(Age)
FROM #B
GROUP BY Name;
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
);
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