2013-06-23 7 views
5

をランク付けすることにより、ポイントと順位の合計でランク私はこれらの分野でのゲームテーブルを持っている:電子メールで私はグループにそれらをしたいのSQL Server:

ID Name  Email  Points 
---------------------------------- 
1  John  [email protected] 120 
2  Test  [email protected]  100 
3  John  [email protected] 80 
4  Bob  [email protected]  50 
5  John  [email protected] 80 

(電子メールは、両方のプレイヤーが関係なく、同じではないことを示します2行目と4つの異なる名前を持つ)としているにも結果のポイントの合計値と最後に入力された名前と最低

にポイントのheighest合計でそれらをランク付けする私は、サンプル表から必要な結果は次のとおりです。

Ranking  Name  Points Games_Played  Average_Points 
------------------------------------------------------------------------------------------ 
1   John  200   2    100 
2   Bob   150   2    75 
3   John  80   1    80 

私はランキング、合計点、平均点を得ることができましたが、最後に入力した名前を取得すると同じテーブルに再び参加する必要があると思います。

どのようにすればいいですか?

答えて

4

名前を表示し、電子メールでグループ化すると、たとえば、 MIN(名前)と重複する名前につながります。フィドルで

Select Rank() over (order by Points desc) as Rank 
,Name,Points,Games_Played,Average_Points 
from 
(
Select Min(Name) as Name,Email,Sum(Points) as Points 
,Count(*) as Games_Played,AVG(Points) as Average_Points 
From @a Group by Email 
) a 
order by Rank 

SQLFiddle

2を使用すると、同じ結果に動作を確認するコメントを解除すべき行をコメントしています。

+0

ファビュラスアンサー。ありがとう.....私の問題を解決し、いくつかの新しいことを学びました。それはマックス(名前)であってはなりませんか?ミン(名前)はどういう意味ですか? –

+0

私は電子メールを使用して、名前を省略することができます。MININimumまたはMAXimumの名前を使用するのはあなた次第ですが、どのような場合でも一種のランダムです。 – bummi

+0

まあ、私はちょうど数字ではなく、名前のためのMaxやMinの機能性を知りたければ、それは辞書の注文のように機能しますか? –

0

私は、これはあなたがここで

select ROW_NUMBER() OVER (ORDER BY sum(r1.points) Desc) as Ranking, 
    r1.name as Name, 
    sum(r1.points) as Points, 
    r3.gplayed as 'Games Played', 
    r2.points 'Average Points' 
from ranks r1 
    join (select avg(points) as points, email from ranks group by email) r2 
     on r1.email = r2.email 
    join (select email, count(*) as gplayed from ranks group by email) r3 
     on r1.email = r3.email 
group by 
    r1.email, 
    r1.name, 
    r2.points, 
    r3.gplayed 

SQL Fiddleで必要なものだと思います。

3

あなたは上向きにSQL-Server 2005のからRanking Functionsを使用することができます。私は、電子メールがある場合には最高点を持つ行を示していますので、結果が異なること

WITH Points 
    AS (SELECT Sum_Points = Sum(points) OVER ( 
           partition BY email), 
       Games_Played = Count(ID) OVER ( 
           partition BY email), 
       Average_Points = AVG(Points) OVER ( 
           partition BY email), 
       Rank = DENSE_RANK() OVER ( 
           Partition BY email Order By Points DESC), 
       * 
     FROM dbo.Game) 
SELECT Ranking=DENSE_RANK()OVER(ORDER BY Sum_Points DESC), 
     Name, 
     Points=Sum_Points, 
     Games_Played, 
     Average_Points 
FROM Points 
WHERE Rank = 1 
Order By Sum_Points DESC; 

DEMO

注意をユニークではないので、 "Bob"の代わりに "Test"を使用します。

以下
2

2008 R2にSQL Serverの2012+、2005年の独立したソリューションであり、2000:2008へ

2012+

CREATE TABLE #PlayerPoints 
    (ID INT PRIMARY KEY 
    , Name VARCHAR(10) NOT NULL 
    , Email VARCHAR(20) NOT NULL 
    , Points INT NOT NULL); 

INSERT INTO #PlayerPoints (ID, Name, Email, Points) 
VALUES 
     (1, 'John', '[email protected]', 120) 
    , (2, 'Test', '[email protected]', 100) 
    , (3, 'John', '[email protected]', 80) 
    , (4, 'Bob', '[email protected]', 50) 
    , (5, 'John', '[email protected]', 80) 

WITH BaseData 
AS 
    (SELECT ID 
     , Email 
     , Points 
     , LastRecordName = LAST_VALUE(Name) OVER 
      (PARTITION BY Email 
      ORDER BY ID DESC 
      ROWS UNBOUNDED PRECEDING) 
    FROM #PlayerPoints) 
SELECT Email 
    , LastRecordName = MAX(LastRecordName) 
    , Points = SUM(Points) 
    , Games_Played = COUNT(*) 
    , Average_Points = AVG(Points) 
FROM BaseData 
GROUP BY Email 
ORDER BY Points DESC; 

2005 R2

CREATE TABLE #PlayerPoints 
    (ID INT PRIMARY KEY 
    , Name VARCHAR(10) NOT NULL 
    , Email VARCHAR(20) NOT NULL 
    , Points INT NOT NULL); 

INSERT INTO #PlayerPoints (ID, Name, Email, Points) 
VALUES 
     (1, 'John', '[email protected]', 120) 
    , (2, 'Test', '[email protected]', 100) 
    , (3, 'John', '[email protected]', 80) 
    , (4, 'Bob', '[email protected]', 50) 
    , (5, 'John', '[email protected]', 80) 

WITH BaseData 
AS 
    (SELECT ID 
     , Email 
     , Name 
     , ReverseOrder = ROW_NUMBER() OVER 
      (PARTITION BY Email 
      ORDER BY ID DESC) 
    FROM #PlayerPoints) 
SELECT pp.Email 
    , LastRecordName = MAX(bd.Name) 
    , Points = SUM(pp.Points) 
    , Games_Played = COUNT(*) 
    , Average_Points = AVG(pp.Points) 
FROM #PlayerPoints pp 
JOIN BaseData bd 
    ON pp.Email = bd.Email 
    AND bd.ReverseOrder = 1 
GROUP BY pp.Email 
ORDER BY Points DESC; 

CREATE TABLE #PlayerPoints 
    (ID INT PRIMARY KEY 
    , Name VARCHAR(10) NOT NULL 
    , Email VARCHAR(20) NOT NULL 
    , Points INT NOT NULL); 

INSERT INTO #PlayerPoints (ID, Name, Email, Points) 
SELECT 1, 'John', '[email protected]', 120 
UNION ALL 
SELECT 2, 'Test', '[email protected]', 100 
UNION ALL 
SELECT 3, 'John', '[email protected]', 80 
UNION ALL 
SELECT 4, 'Bob', '[email protected]', 50 
UNION ALL 
SELECT 5, 'John', '[email protected]', 80; 

SELECT pp.Email 
    , LastRecordName = MAX(sppmi.Name) 
    , Points = SUM(pp.Points) 
    , Games_Played = COUNT(*) 
    , Average_Points = AVG(pp.Points) 
FROM #PlayerPoints pp 
JOIN 
    (SELECT spp.Email 
     , spp.Name 
    FROM #PlayerPoints spp 
    JOIN 
     (SELECT Email 
      , MaximumID = MAX(ID) 
     FROM #PlayerPoints 
     GROUP BY Email) mi 
     ON spp.ID = mi.MaximumID) sppmi 
    ON pp.Email = sppmi.Email 
GROUP BY pp.Email 
ORDER BY Points DESC; 
+0

+1。 。 。 Yoursは名前に対する実際の制約を正しく処理する唯一のソリューションです。私はソリューションが限られていると思うが、OPで指定されていないSQL Server 2012でしか使用できない機能に依存している。 –

+0

私は2005年のソリューションも追加します。 –

+0

2000年のソリューションを追加しました。 –

0

@RegisteredUserのソリューションだけがnameの制約を処理しているようです。しかし、それはので、ここでは、SQL Server 2012を必要とし、より一般的なソリューションです。

 Select dense_rank() over (order by sum(points) desc) as ranking 
      max(case when islastid = 1 then Name end) as Name, Email, Sum(Points) as Points, 
      Count(*) as Games_Played, AVG(Points) as Average_Points 
     From (select g.*, 
        row_number() over (partition by email order by id desc) as islastid 
      from games g 
      ) t 
     Group by Email; 

あなたがrank()dense_rank()の間で選択する問題で十分な情報を持っていません。

また、ウィンドウ関数と集計関数を混在させることができるため、このバージョンは他のバージョンよりも簡単です。