所以我使用的是SQL Server,我有两个类似于下面的表:
人
人员姓名
1个鲍勃
2比尔
3芭芭拉
4邦尼
类
人员ID类
1个数学
1科学
2数学
2英语
3科学
3英语
4英语
4数学
4科学
我需要编写一个查询,该查询返回占用最多类的人的名称和名称。因此,运行上述案例查询后的唯一结果应该是名称'Bonnie'。
如果是平局,则应返回多个名称。
我的尝试如下:
`Select People.Name
from People inner join Classes
On People.PersonID = Classes.PersonID
Group by People.Name
Having max(Classes.PersonID)`
最后一行在SQL Server中不起作用,我不能为我的生活找出如何重新编写代码以使其正常运行。
有什么想法吗?
答案 0 :(得分:1)
SELECT TOP 1
name
FROM (
SELECT name,
COUNT(p.PersonID) as cnt
FROM People p
JOIN Classes c
ON p.PersonID = c.PersonID
GROUP BY name
) a
ORDER BY cnt DESC
答案 1 :(得分:0)
试试这个
WITH CTE
AS
(
SELECT
SeqNo = ROW_NUMBER() OVER(ORDER BY COUNT(1) DESC),
P.PersonId,
Cnt = COUNT(1)
FROM Person p
INNER JOIN Classes C
ON P.PersonId = C.PersonId
GROUP BY p.PersonId
)
SELECT
*
FROM Person P2
WHERE EXISTS
(
SELECT 1 FROM CTE WHERE PersonId = p2.PersonId AND SeqNo = 1
)
答案 2 :(得分:0)
T-SQL提供ranking functions,允许您根据字段或聚合计算排名。
鉴于这些表格:
declare @people table (personid int primary key,name nvarchar(20))
declare @classes table (personid int ,class nvarchar(20))
insert into @people(personid,name)
values
(1,'Bob'),
(2,'Bill'),
(3,'Barbara'),
(4,'Bonnie'),
(5,'Joe')
insert into @classes (personid,class)
values
(1,'Math'),
(1,'Science'),
(2,'Math'),
(2,'English'),
(3,'Science'),
(3,'English'),
(4,'English'),
(4,'Math'),
(4,'Science')
(5,'Science')
以下查询将根据所选课程数计算人员排名:
select p.name,count(*) As Classes,rank() over (order by count(*) desc) as Rank
from @classes c
inner join @people p on p.personid=c.personid
group by p.name
返回Bonnie有3个班级。所有其他学生在2个班级中排名第二:
name Classes Rank
------- ------- ----
Bonnie 3 1
Barbara 2 2
Bill 2 2
Bob 2 2
Joe 1 5
如果有关系, RANK
将跳过职位。这就是Joe
排名为5的原因。
您无法在WHERE或HAVING子句中使用排名功能。要仅返回您需要使用子查询或CTE的第一个学生,例如:
select name,classes
from (
select p.name,count(*) As Classes,rank() over (order by count(*) desc) as Rank
from @classes c
inner join @people p on p.personid=c.personid
group by p.name
) r
where rank=1
或者
;with r as (
select p.name,count(*) As Classes,rank() over (order by count(*) desc) as Rank
from @classes c
inner join @people p on p.personid=c.personid
group by p.name
)
select name,classes
from r
where rank=1
两个查询都将返回:
name Classes
------- -------
Bonnie 3
如果你想找到N个最好的学生,你应该使用DENSE_RANK并返回排名小于或等于N的行。DENSE_RANK
Joe的排名将是3。
以下查询将返回前两位的学生:
with r as (
select p.name,count(*) As Classes,dense_rank() over (order by count(*) desc) as Rank
from @classes c
inner join @people p on p.personid=c.personid
group by p.name
)
select name,classes
from r
where rank<=2
答案 3 :(得分:0)
使用TOP查询获取大多数类的人员ID。然后从人员表中选择人员姓名:
select name
from people
where people_id in
(
select top(1) with ties person_id
from classes
group by person_id
order by count(*) desc
);
答案 4 :(得分:0)
好的,我通过Having COUNT(*) >= ALL (Select..)
命令行找到了最有效的方法
代码如下:
Select People.Name as 'Most Classes Taken:'
from People inner join Classes
On People.PersonID = Classes.PersonID
Group by People.Name
Having count(*)>=ALL (Select count(*) from Classes group by Classes.PersonID)