查找每位客户的每个类别的最新评分。

huangapple go评论69阅读模式
英文:

Find the latest rating for each category for each customer

问题

以下是要翻译的SQL代码的部分:

select
	coalesce(a.StudentID,b.StudentID) as StudentID,
	a.rating as RAPID_Rating,
	RAPID_Games,
	b.rating as BLITZ_Rating,
	BLITZ_Games,
	RAPID_Games + BLITZ_Games as Total_Games
	
from 
(select 
	StudentID, 
 	ScoreType,
	rating,
	count(rating) over(partition by StudentID,ScoreType) as RAPID_Games,
	row_number() over(partition by StudentID,ScoreType order by date desc) as RNUM
from rating 
	where ScoreType ='RAPID'
) a join (
	select 
	StudentID, 
 	ScoreType,
	rating,
	count(rating) over(partition by StudentID,ScoreType) as BLITZ_Games,
	row_number() over(partition by StudentID,ScoreType order by date desc) as RNUM
from rating 
	where ScoreType ='BLITZ'
) b on a.StudentID = b.StudentID 
where a.RNUM = 1 and b.RNUM = 1

希望这对你有所帮助。

英文:

The data in the rating table looks like this:

StudentID Rating ScoreType Date
1 12 RAPID 2023-01-01
1 15 RAPID 2023-01-10
1 20 RAPID 2023-02-15
1 25 RAPID 2023-02-20
1 25 BLITZ 2023-03-01
1 33 BLITZ 2023-03-20
2 17 RAPID 2023-01-15
2 19 BLITZ 2023-02-06

What I am trying to build is like this:

StudentID RAPID_Rating RAPID_Games BLITZ_Rating BLITZ_Games Total Games
1 25 4 33 2 6
2 17 1 19 1 2

The data should be one row for each student

Column definitions of the expected output:

RAPID_Rating : Latest rating value based on date where ScoreType = 'RAPID'

RAPID_Games: Total number of RAPID games played by each student

BLITZ_Rating: Latest rating value based on date where ScoreType = 'BLITZ'

BLITZ_Games: Total number of BLIRZ games played by each student

Total Games: Total games played by each student

The SQL Code that I have tried:

select
	coalesce(a.StudentID,b.StudentID) as StudentID,
	a.rating as RAPID_Rating,
	RAPID_Games,
	b.rating as BLITZ_Rating,
	BLITZ_Games,
	RAPID_Games + BLITZ_Games as Total_Games
	
from 
(select 
	StudentID, 
 	ScoreType,
	rating,
	count(rating) over(partition by StudentID,ScoreType) as RAPID_Games,
	row_number() over(partition by StudentID,ScoreType order by date desc) as RNUM
from rating 
	where ScoreType ='RAPID'
) a join (
	select 
	StudentID, 
 	ScoreType,
	rating,
	count(rating) over(partition by StudentID,ScoreType) as BLITZ_Games,
	row_number() over(partition by StudentID,ScoreType order by date desc) as RNUM
from rating 
	where ScoreType ='BLITZ'
) b on a.StudentID = b.StudentID 
where a.RNUM = 1 and b.RNUM = 1

I have to do this calculation for another 2 categories then that will add up another 2 sub queries. Is there anyway to optimize this SQL code?

答案1

得分: 2

这里我们可以使用 ROW_NUMBER 与条件聚合:

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY StudentID, ScoreType ORDER BY Date DESC) rn
    FROM rating
)

SELECT
    StudentID,
    MAX(Rating) FILTER (WHERE ScoreType = 'RAPID' AND rn = 1) AS RAPID_Rating,
    COUNT(*) FILTER (WHERE ScoreType = 'RAPID') AS RAPID_Games,
    MAX(Rating) FILTER (WHERE ScoreType = 'BLITZ' AND rn = 1) AS BLITZ_Rating,
    COUNT(*) FILTER (WHERE ScoreType = 'BLITZ') AS BLITZ_Games,
    COUNT(*) AS "Total Games"
FROM cte
GROUP BY StudentID
ORDER BY StudentID;
英文:

We can use ROW_NUMBER along with conditional aggregation here:

<!-- language: sql -->

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY StudentID, ScoreType ORDER BY Date DESC) rn
    FROM rating
)

SELECT
    StudentID,
    MAX(Rating) FILTER (WHERE ScoreType = &#39;RAPID&#39; AND rn = 1) AS RAPID_Rating,
    COUNT(*) FILTER (WHERE ScoreType = &#39;RAPID&#39;) AS RAPID_Games,
    MAX(Rating) FILTER (WHERE ScoreType = &#39;BLITZ&#39; AND rn = 1) AS BLITZ_Rating,
    COUNT(*) FILTER (WHERE ScoreType = &#39;BLITZ&#39;) AS BLITZ_Games,
    COUNT(*) AS &quot;Total Games&quot;
FROM cte
GROUP BY StudentID
ORDER BY StudentID;

huangapple
  • 本文由 发表于 2023年6月5日 00:02:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76401278.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定