Sql 如何选择每月得分最高的ID
我对SQL相当陌生。我的桌子是空的Sql 如何选择每月得分最高的ID,sql,sql-server,Sql,Sql Server,我对SQL相当陌生。我的桌子是空的 id mark datetimes ------|-----|------------ 1001 | 10 | 2011-12-20 1002 | 11 | 2012-01-10 1005 | 12 | 2012-01-10 1003 | 10 | 2012-01-10 1004 | 11 | 2018-10-10 1006 | 12 |
id mark datetimes
------|-----|------------
1001 | 10 | 2011-12-20
1002 | 11 | 2012-01-10
1005 | 12 | 2012-01-10
1003 | 10 | 2012-01-10
1004 | 11 | 2018-10-10
1006 | 12 | 2018-10-19
1007 | 13 | 2018-03-12
1008 | 15 | 2018-03-13
我需要在每个月底选择一个得分最高的ID(年份也很重要),ID可以重复
我期望的输出是
id mark
-----|----
1001 | 10
1005 | 12
1006 | 12
1008 | 15
到目前为止,我每个月只能得到最高的价值
Select Max(Mark)'HighestMark'
From StudentMark
Group BY Year(datetimes), Month(datetimes)
当我试图
Select Max(Mark)'HighestMark', ID
From StudentMark
Group BY Year(datetimes), Month(datetimes), ID
我明白了
Id HighestMark
----------- ------------
1001 10
1002 11
1003 12
1004 10
1005 11
1006 12
1007 13
1008 15
我看不到一个查询就可以做到这一点。但是我们可以很容易地使用一个子查询来查找每个学生当月的最终分数,并使用另一个子查询来查找最终分数最高的学生
WITH cte AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY ID, CONVERT(varchar(7), datetimes, 126)
ORDER BY datetimes DESC) rn
FROM StudentMark
)
SELECT ID, Mark AS HighestMark
FROM
(
SELECT *,
RANK() OVER (PARTITION BY CONVERT(varchar(7), datetimes, 126)
ORDER BY Mark DESC) rk
FROM cte
WHERE rn = 1
) t
WHERE rk = 1
ORDER BY ID;
您可以尝试以下方法 使用
行号()
SELECT * FROM
(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY YEAR(DATETIMES)
,MONTH(DATETIMES) ORDER BY MARK DESC) AS RN
FROM [MY_TABLE]
)T WHERE RN=1
SELECT TOP 1 WITH TIES ID, mark AS HighestMarks
FROM [MY_TABLE]
ORDER BY ROW_NUMBER() OVER (PARTITION BY YEAR(datetimes)
,MONTH(datetimes) ORDER BY mark DESC)
使用带领带的
SELECT * FROM
(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY YEAR(DATETIMES)
,MONTH(DATETIMES) ORDER BY MARK DESC) AS RN
FROM [MY_TABLE]
)T WHERE RN=1
SELECT TOP 1 WITH TIES ID, mark AS HighestMarks
FROM [MY_TABLE]
ORDER BY ROW_NUMBER() OVER (PARTITION BY YEAR(datetimes)
,MONTH(datetimes) ORDER BY mark DESC)
示例:
WITH MY AS
(
SELECT
* FROM (VALUES
(1001 , 10 , '2011-12-20'),
(1002 , 11 , '2012-01-10'),
(1005 , 12 , '2012-01-10'),
(1003 , 10 , '2012-01-10'),
(1004 , 11 , '2018-10-10'),
(1006 , 12 , '2018-10-19'),
(1007 , 13 , '2018-03-12'),
(1008 , 15 , '2018-03-13')
) T( id , mark , datetimes)
)
SELECT ID,Mark as HighestMark FROM
(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY YEAR(DATETIMES),MONTH(DATETIMES) ORDER BY MARK DESC) AS RN
FROM MY
)T WHERE RN=1
输出:
ID HighestMark
1001 10
1005 12
1008 15
1006 12
如果有超过1名学生获得相同的最高分数,则使用
RANK
select id, mark
from
(select *,
rank() over( partition by convert(char(7), datetimes, 111) order by mark desc) seqnum
from studentMark ) t
where seqnum = 1
在下面的查询中,您为Group By包含了ID列,因此,它将考虑所有ID的所有数据
Select Max(Mark)'HighestMark', ID From StudentMark Group BY Year(datetimes), Month(datetimes), ID
请从此脚本中删除ID列,然后重试。这应该可以:
select s.ID, t.Mark, t.[Month year] from Studentmark s
inner join (
Select
Max(Mark)'HighestMark'
,cast(Year(datetimes) as varchar(10)) +
cast(Month(datetimes) as varchar(10)) [month year]
From StudentMark
Group BY cast(Year(datetimes) as varchar(10))
+ cast(Month(datetimes) as varchar(10))) t on t.HighestMark = s.mark and
t.[month year] = cast(Year(s.datetimes) as varchar(10)) + cast(Month(s.datetimes) as varchar(10))
如果出于某种原因您厌恶子查询,您实际上可以这样做:
select distinct
first_value(id) over (partition by year(datetimes), month(datetime) order by mark desc) as id
max(mark) over (partition by year(datetimes), month(datetime))
from StudentMark;
或:
在这种情况下,您可以通过使用
rank()
或densite\u rank()
而不是row\u number()
问题来获取所有学生的情况。然而,请注意,从最终结果中去掉分区(年/月组合)会使它们变得神秘。@Clockwork Muse不,如果我读对了,这不是这个问题的重复。否则,OP的GROUP BY
查询应该已经足够了,但显然不够。@TimBiegeleisen-那么为什么答案在功能上是相同的呢?这是最好的解决方案。我不明白为什么人们希望在日期上使用字符串函数,而内置的日期函数却做同样的事情。虽然Row_Number()超出了我所了解的范围,我花了很快的时间在谷歌上才弄清楚到底发生了什么。总而言之,这非常优雅,谢谢