不确定如何在SO上提出后续问题,但这是参考之前的问题: Fetch one row per account id from list
我正在使用的查询是:
SELECT *
FROM scores s1
WHERE accountid NOT IN (SELECT accountid FROM scores s2 WHERE s1.score < s2.score)
ORDER BY score DESC
这会选择最高分,并将结果限制为每行一行;他们的最高分。
最后一个障碍是此查询返回多行,以获得多次出现其最高分的会计。因此,如果accountid 17得分为40分,75分,30分,75分,则查询返回得分为75的两行。
任何人都可以修改此查询(或提供更好的查询)来修复此案例,并真正将其限制为每个帐户ID一行吗?
再次感谢!
答案 0 :(得分:2)
select accountid, max(score) from scores group by accountid;
答案 1 :(得分:2)
如果您只对accountid和得分感兴趣,那么您可以使用Paul上面给出的简单GROUP BY查询。
SELECT accountid, MAX(score)
FROM scores
GROUP BY accountid;
如果您需要得分表中的其他属性,那么您可以通过以下查询从行中获取其他属性:
SELECT s1.*
FROM scores AS s1
LEFT OUTER JOIN scores AS s2 ON (s1.accountid = s2.accountid
AND s1.score < s2.score)
WHERE s2.accountid IS NULL;
但是这仍然会给出多行,在您的示例中,给定的accountid有两个分数与其最大值匹配。要进一步将结果集减少到单行,例如具有最新gamedate的行,请尝试:
SELECT s1.*
FROM scores AS s1
LEFT OUTER JOIN scores AS s2 ON (s1.accountid = s2.accountid
AND s1.score < s2.score)
LEFT OUTER JOIN scores AS s3 ON (s1.accountid = s3.accountid
AND s1.score = s3.score AND s1.gamedate < s3.gamedate)
WHERE s2.accountid IS NULL
AND s3.accountid IS NULL;
答案 2 :(得分:1)
如果您的RDBMS支持它们,那么分析函数将是一个很好的方法,特别是如果您需要该行的所有列。
select ...
from (
select accountid,
score,
...
row_number() over
(partition by accountid
order by score desc) score_rank
from scores)
where score_rank = 1;
在您描述的情况下,返回的行是不确定的,但您可以轻松修改分析函数,例如通过订购(score desc,test_date desc)来获取最近的两个匹配的高分。
基于排名的其他分析函数将达到类似的目的。
如果您不介意重复,那么以下可能比我当前的方法更有效:
select ...
from (
select accountid,
score,
...
max(score) over (partition by accountid) max_score
from scores)
where score = max_score;
答案 3 :(得分:0)
如果要选择列的子集,则可以使用DISTINCT关键字过滤结果。
SELECT DISTINCT UserID, score
FROM scores s1
WHERE accountid NOT IN (SELECT accountid FROM scores s2 WHERE s1.score < s2.score)
ORDER BY score DESC
答案 4 :(得分:0)
您的数据库支持不同吗?与选择不同的x来自y?
答案 5 :(得分:0)
此解决方案适用于MS SQL,为您提供整行。
SELECT *
FROM scores
WHERE scoreid in
(
SELECT max(scoreid)
FROM scores as s2
JOIN
(
SELECT max(score) as maxscore, accountid
FROM scores s1
GROUP BY accountid
) sub ON s2.score = sub.maxscore AND s2.accountid = s1.accountid
GROUP BY s2.score, s2.accountid
)