繁体   English   中英

从列表中获取每个帐户ID一行,第2部分

[英]Fetch one row per account id from list, part 2

不确定如何在SO上提出后续问题,但这是参考之前的一个问题: 从列表中获取每个帐户ID一行

我正在使用的查询是:

SELECT *
FROM scores s1
WHERE accountid NOT IN (SELECT accountid FROM scores s2 WHERE s1.score < s2.score)
ORDER BY score DESC

这将选择最高分,并将结果限制为每行一行; 他们的最高分。

最后一个障碍是此查询返回多行,以获得多次出现其最高分的accountid。 因此,如果accountid 17的分数为40,75,30,75,则查询返回得分为75的两行。

任何人都可以修改此查询(或提供更好的查询)来修复此案例,并真正将其限制为每个帐户ID一行吗?

再次感谢!

select accountid, max(score) from scores group by accountid;

如果您只对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;

如果您的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;

如果要选择列的子集,则可以使用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

您的数据库支持不同吗? 如同从y中选择不同的x?

此解决方案适用于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
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM