2008-09-25 51 views
3

不知道如何問一個後續的SO,但是這是在參考前面一個問題: Fetch one row per account id from list取每從列表帳戶ID一排,第2部分

我正在使用的查詢是:

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

這會選擇最高分數,並將結果限制爲每行一個行;他們的最高分。

最後一關是,這個查詢返回多行對於具有自己的最高分多次出現accountids。因此,如果accountid 17的分數爲40,75,30,75,則查詢將返回兩行,分數爲75.

任何人都可以修改此查詢(或提供更好的查詢)來解決此問題,並將其限制爲每個帳戶ID一行?再次

謝謝!

+0

我需要所有列返回,不只是accounid +分數,所以最大和獨特的麻煩。 – Kenzie 2008-09-25 01:59:51

回答

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; 
+0

兩個自我加入?特別是對於Oracle來說,一個大型連接將會通過散列連接執行得最好,並且需要equi連接。我認爲對於一個1億行的表格查詢來說表現會很差,所以我會記下它的原因。 – 2008-09-25 13:10:36

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 
+0

獨特也限制了我可以從行中獲得accountid +分數。我需要所有領域。 – Kenzie 2008-09-25 01:58:15

0

您的數據庫支持不同?在選擇不同的X從Y?

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

我應該更清楚。我需要整排,而不僅僅是accountid +分數。馬克斯並沒有給我我需要的東西。 – Kenzie 2008-09-25 01:57:36

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; 

返回該行是在你所描述的情況不確定,但你可以很容易地修改解析功能,例如通過訂購的(得分降序,test_date遞減),以獲得更近的兩個匹配的高分數。根據排名

其他分析功能將實現類似的目的。

如果你不介意重複那麼下面大概會我比你目前的方法效率:

select ... 
from (
    select accountid, 
      score, 
      ... 
      max(score) over (partition by accountid) max_score 
    from scores) 
where score = max_score; 
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 
)