如何获得每个人在本赛季最佳十分的总和?

时间:2011-07-23 10:53:25

标签: mysql database

我有一个25场比赛结果的数据库。但是只有每个人最好的十分数。 任何人都可以告诉我如何只计算每个人的前十个分数,并显示该总和中使用的最低分数(他们的第十好)。 该数据库具有PlayerName,TournamentID,Points 例如

 - TounamentID  PlayerName  Points
 - 1             Jo           100
 - 1             Tel          50
 - 1             Kevin        75
 - 2             Jo           100
 - 2             Tel          50
 - 2             Kevin        75
 - 3             Jo           100
 - 3             Tel          50
 - 3             Kevin        75
 - 4             Jo           100
 - 4             Tel          50
 - 4             Kevin        75
 - 5             Jo           100
 - 5             Tel          50
 - 5             Kevin        75 etc

非常感谢提前

编辑 1

目前我有这种工作,虽然它不能很好地处理重复的分数,如果有重复,实际上最终可以加上前11名;

SELECT X.PlayerName, Sum(X.Points) AS SumOfPoints, Min(X.Points) AS Target
FROM SoP11PreBats AS X
WHERE (((10)>(SELECT count(*)
       FROM SoP11PreBats
      WHERE PlayerName = X.PlayerName
        AND Points > X.Points )))
GROUP BY X.PlayerName
ORDER BY Sum(X.Points) DESC;

6 个答案:

答案 0 :(得分:1)

这样的事情一次对一个玩家有效:

SELECT SUM(n), MIN(n) FROM
  (SELECT   points AS n
   FROM     table
   WHERE    PlayerName = ?
   ORDER BY n DESC
   LIMIT    10
  )

我不确定如何扩展它以为每个播放器生成一个表。

答案 1 :(得分:1)

SELECT test.playername, sum(top10.score), MIN(top10.score)
FROM test
LEFT JOIN (SELECT playername, score FROM test ORDER BY score DESC LIMIT 10) top10
ON top10.playername = test.playername
GROUP BY test.playername

编辑:使用子选择结果显示上述方法,并且连接不会成功。因为您在子选择中限制结果,所以不会导致一组最多10个记录PER playername。
接下来的方法是做一些像

这样的事情
SELECT pk, name, score from test where
pk IN (SELECT pk FROM test t2 WHERE t2.name = name ORDER BY score DESC LIMIT 10)

这可以创建要加入的正确记录集。但是IN子句(尚未)内部不支持LIMIT。所以这不会编译。

EIDT2:我能想到的最终方法是这样的:

select distinct test.name
, (SELECT sum(t2.score) FROM (select t3.score FROM test t3 WHERE t3.name = test.name ORDER BY score desc LIMIT 10) t2)
, (SELECT min(t2.score) FROM (select t3.score FROM test t3 WHERE t3.name = test.name ORDER BY score desc LIMIT 10) t2)
FROM test

这个也不会编译,因为最里面的test.name在哪里无法正确解析。

我不认为你想要做的事情目前可以在mysql的1个单一查询中完成,但我很好奇是否有人可以证明我错了。

答案 2 :(得分:1)

好的,我得到了它的工作,但它是关于我能想到的最讨厌的sql hack,我不确定你是否应该考虑将它投入到这样的生产中。它也只能在mysql上运行:

select PlayerName, sum(Points), min(Points) from 
(select distinct SoP11PreBats.PlayerName, (SELECT t2.Points FROM test t2 WHERE t2.PlayerName = SoP11PreBats.PlayerName ORDER BY Points desc LIMIT 1) as Points FROM test 
UNION ALL
select distinct SoP11PreBats.PlayerName, (SELECT t2.Points FROM test t2 WHERE t2.PlayerName = SoP11PreBats.PlayerName ORDER BY Points desc LIMIT 1,1) as Points FROM test 
UNION ALL
select distinct SoP11PreBats.PlayerName, (SELECT t2.Points FROM test t2 WHERE t2.PlayerName = SoP11PreBats.PlayerName ORDER BY Points desc LIMIT 2,1) as Points FROM test 
UNION ALL
select distinct SoP11PreBats.PlayerName, (SELECT t2.Points FROM test t2 WHERE t2.PlayerName = SoP11PreBats.PlayerName ORDER BY Points desc LIMIT 3,1) as Points FROM test 
UNION ALL
select distinct SoP11PreBats.PlayerName, (SELECT t2.Points FROM test t2 WHERE t2.PlayerName = SoP11PreBats.PlayerName ORDER BY Points desc LIMIT 4,1) as Points FROM test 
UNION ALL
select distinct SoP11PreBats.PlayerName, (SELECT t2.Points FROM test t2 WHERE t2.PlayerName = SoP11PreBats.PlayerName ORDER BY Points desc LIMIT 5,1) as Points FROM test 
UNION ALL
select distinct SoP11PreBats.PlayerName, (SELECT t2.Points FROM test t2 WHERE t2.PlayerName = SoP11PreBats.PlayerName ORDER BY Points desc LIMIT 6,1) as Points FROM test 
UNION ALL
select distinct SoP11PreBats.PlayerName, (SELECT t2.Points FROM test t2 WHERE t2.PlayerName = SoP11PreBats.PlayerName ORDER BY Points desc LIMIT 7,1) as Points FROM test 
UNION ALL
select distinct SoP11PreBats.PlayerName, (SELECT t2.Points FROM test t2 WHERE t2.PlayerName = SoP11PreBats.PlayerName ORDER BY Points desc LIMIT 8,1) as Points FROM test 
UNION ALL
select distinct SoP11PreBats.PlayerName, (SELECT t2.Points FROM test t2 WHERE t2.PlayerName = SoP11PreBats.PlayerName ORDER BY Points desc LIMIT 9,1) as Points FROM test 
) top10
group by name

答案 3 :(得分:0)

我觉得这不起作用:

SELECT *
FROM
  ( SELECT pd.PlayerName
         , ( SELECT SUM(t10.Points)
             FROM
               ( SELECT t10.Points
                 FROM SoP11PreBats AS t10
                 WHERE t10.PlayerName = pd.PlayerName
                 ORDER BY t10.Points DESC
                 LIMIT 10
               ) AS x
           ) AS Sum10
         , ( SELECT t10.Points
             FROM SoP11PreBats AS t10
             WHERE t10.PlayerName = pd.PlayerName
             ORDER BY t10.Points DESC
             LIMIT 1 OFFSET 9
           ) AS TenthBest
    FROM 
        ( SELECT DISTINCT PlayerName
          FROM SoP11PreBats
        ) AS pd
  ) AS y
ORDER BY Sum10 DESC

但这会:

SELECT pb.PlayerName  AS PlayerName  
     , COALESCE(SUM(p.Points),0) + pb.TenthBest*(10-COUNT(p.Points))
                      AS SumOfPoints
     , pb.TenthBest   AS Target
FROM
  ( SELECT pd.PlayerName
         , ( SELECT t10.Points
             FROM SoP11PreBats AS t10
             WHERE t10.PlayerName = pd.PlayerName
             ORDER BY t10.Points DESC
             LIMIT 1 OFFSET 9
           ) AS TenthBest
    FROM 
        ( SELECT DISTINCT PlayerName
          FROM SoP11PreBats
        ) AS pd
  ) AS pb
  LEFT JOIN SoP11PreBats AS p
    ON  p.PlayerName = pb.PlayerName
    AND p.Points > pb.TenthBest
GROUP BY pb.PlayerName
ORDER BY SumOfPoints DESC

答案 4 :(得分:0)

这有效(见下面的测试输出):

set @count:=0, @player:='';
SELECT 
    PlayerName,
    SUM(Points) as sum_top_10, 
    MIN(Points) as min_top_10
FROM (SELECT PlayerName, Points
    FROM (SELECT
    Points, 
        @count := if (@player != PlayerName, 0, @count + 1) as count, 
        @player := PlayerName as PlayerName
        FROM (SELECT PlayerName, Points FROM SoP11PreBATS order by 1, 2 desc) x) y
    where count < 10) z
group by 1;

以下是测试,使用OP的数据,以及'Jo'的额外行,以产生超过10行:

create table SoP11PreBATS (TounamentID int, PlayerName text,  Points int);
delete from SoP11PreBATS;
insert into SoP11PreBATS values
(1, 'Jo', 100), (1, 'Tel', 50), (1, 'Kevin', 75), (2, 'Jo', 100), (2, 'Tel', 50),
(2, 'Kevin', 75), (3, 'Jo', 100), (3, 'Tel', 50), (3, 'Kevin', 75), (4, 'Jo', 100),
(4, 'Tel', 50), (4, 'Kevin', 75), (5, 'Jo', 100), (5, 'Tel', 50), (5, 'Kevin', 75),
(5, 'Jo', 50), (6, 'Jo', 75), (7, 'Jo', 100), (8, 'Jo', 50), (9, 'Jo', 75),
(10, 'Jo', 50), (11, 'Jo', 75), (12, 'Jo', 100);
select * from SoP11PreBATS where playername = 'Jo' order by points desc;
+-------------+------------+--------+
| TounamentID | PlayerName | Points |
+-------------+------------+--------+
|           1 | Jo         |    100 |
|           2 | Jo         |    100 |
|           3 | Jo         |    100 |
|           4 | Jo         |    100 |
|           5 | Jo         |    100 |
|           7 | Jo         |    100 |
|          12 | Jo         |    100 |
|           6 | Jo         |     75 |
|           9 | Jo         |     75 |
|          11 | Jo         |     75 |
|           5 | Jo         |     50 |
|           8 | Jo         |     50 |
|          10 | Jo         |     50 |
+-------------+------------+--------+
-- Inspection shows Jo should have 925 as sum and 75 as min
-- Ran query above and got:
+------------+------------+------------+
| PlayerName | sum_top_10 | min_top_10 |
+------------+------------+------------+
| Jo         |        925 |         75 |
| Kevin      |        375 |         75 |
| Tel        |        250 |         50 |
+------------+------------+------------+
-- Test output correct

答案 5 :(得分:0)

我认为这是有效的,它只使用一个派生表:

  SELECT @row := 0, @pp := NULL, @min := 0;
  SELECT Player,
         SUM(Points) AS Points,
         MIN(Points) AS MinPoints
    FROM (
  SELECT Player,
         Points,
         @row := IF(
           IFNULL(@pp, '') <> Player AND NOT (@pp := Player),
           1,
           @row + 1
         ) AS Row
    FROM SoP11PreBats
ORDER BY Player, Points DESC
) tmp
   WHERE tmp.Row <= 10
GROUP BY Player;

测试数据:

CREATE TABLE `SoP11PreBats` (
 `TournamentID` int(11) NOT NULL,
 `Player` varchar(255) NOT NULL,
 `Points` int(11) NOT NULL
);

INSERT INTO SoP11PreBats (TournamentID, Player, Points) VALUES
(15, 'Jo',     10),
(14, 'Jo',     20),
(13, 'Jo',     30),
(12, 'Jo',     40),
(11, 'Jo',     50),
(10, 'Jo',     60),
( 9, 'Jo',     70),
( 8, 'Jo',     80),
( 7, 'Jo',     90),
( 6, 'Jo',    100),
( 5, 'Jo',    110),
( 4, 'Jo',    120),
( 3, 'Jo',    130),
( 2, 'Jo',    140),
( 1, 'Jo',    150),
( 1, 'Tel',    15),
( 2, 'Tel',    25),
( 3, 'Tel',    35),
( 4, 'Tel',    45),
( 5, 'Tel',    55),
( 6, 'Tel',    65),
( 7, 'Tel',    75),
( 8, 'Tel',    85),
( 9, 'Tel',    95),
(10, 'Tel',   105),
(11, 'Tel',   115),
(12, 'Tel',   125),
(13, 'Tel',   135),
(14, 'Tel',   145),
(15, 'Tel',   155),
( 1, 'Kevin',  10),
( 2, 'Kevin',  20),
( 3, 'Kevin',  30),
( 4, 'Kevin',  40),
( 5, 'Kevin',  50),
( 6, 'Kevin',  60),
( 7, 'Kevin',  70),
( 8, 'Kevin',  80),
( 9, 'Kevin',  90),
(10, 'Kevin', 100),
(11, 'Kevin', 110),
(12, 'Kevin', 120),
(13, 'Kevin', 130),
(14, 'Kevin', 140),
(15, 'Kevin', 150);

结果:

+--------+--------+-----------+
| Player | Points | MinPoints |
+--------+--------+-----------+
| Jo     |   1050 |        60 |
| Kevin  |   1050 |        60 |
| Tel    |   1100 |        65 |
+--------+--------+-----------+