2014-11-21 28 views
0

我有一张表,其中有不同用户的明智测验分数。我想每个日期都加载前5名得分手。每个日期载入前5条记录

表样本创建语句

CREATE TABLE `subscriber_score` (
    `msisdn` varchar(25) COLLATE utf8_unicode_ci NOT NULL, 
    `date` date NOT NULL, 
    `score` int(11) NOT NULL DEFAULT '0', 

    `total_questions_sent` int(11) NOT NULL DEFAULT '0', 

    `total_correct_answers` int(11) NOT NULL DEFAULT '0', 
    `total_wrong_answers` int(11) NOT NULL DEFAULT '0', 

    PRIMARY KEY (`msisdn`,`date`), 
    KEY `fk_subscriber_score_subscriber1` (`msisdn`), 
    CONSTRAINT `fk_subscriber_score_subscriber1` FOREIGN KEY (`msisdn`) REFERENCES `subscriber` (`msisdn`) ON DELETE NO ACTION ON UPDATE NO ACTION 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

查询,我已经试过

SELECT subscriber.msisdn AS msisdn,subscriber.name AS name,subscriber.gender AS gender,tmp2.score AS score,tmp2.date AS winning_date 
FROM subscriber, 
    (SELECT msisdn,tmp.date,tmp.score 
    FROM subscriber_score, 
      (SELECT date,MAX(score) AS score 
      FROM subscriber_score 
      WHERE date > '2014-10-10' AND date < '2014-11-10' GROUP BY date) 
      tmp 
    WHERE subscriber_score.date=tmp.date AND subscriber_score.score=tmp.score) 
tmp2 
WHERE subscriber.msisdn=tmp2.msisdn ORDER BY winning_date 

实际输出:只有一个,每日期头号射手所示。

通缉输出需要每个日期的前5(或说10)记录。

+0

什么5?编辑您的问题并提供样本输出和所需结果。 – 2014-11-21 11:32:49

回答

0

参照此查询其没有完成,但希望它有助于

SELECT SCORE 
FROM table 
WHERE date='somedate' 
ORDER BY SCORE DESC LIMIT 5 
+0

这给出了只有一个日期的记录。我需要选定日期范围内每个日期的5条记录。 – 2014-11-21 11:48:15

+0

验证您是否有特定日期的5条记录。 – 2014-11-21 11:49:47

0
select bc.msisdn msisdn,bc.name name,bc.gender gender,ab.score score,ab.date winning_date 
    (
     select msisdn,date,score, 
     dense_rank() over (partition by date order by score desc) rnk 
     from subscriber_score 
    ) ab,subscriber bc 
where bc.msisdn=ab.msisdn and ab.rnk<=5 
order by winning_date  ; 

这就是你如何获得在Oracle SQL你的问题的解决方案。

+0

最新问题,亲爱的 – 2014-11-21 11:51:31

+0

,但他的问题也标记为sql – 2014-11-21 11:52:51

+0

,否则他必须在他的问题中声明他在mysql中查找结果 – 2014-11-21 11:56:11

0

试试下面

 SELECT subscriber.msisdn AS msisdn,subscriber.name AS name,subscriber.gender AS gender,tmp2.score AS score,tmp2.date AS winning_date 
     FROM subscriber inner join 
     (select msisdn,date, score, ROW_NUMBER() OVER(PARTITION BY date ORDER BY score DESC) AS Row 
     FROM subscriber_score 
     WHERE date > '2014-10-10' AND date < '2014-11-10' GROUP BY date) 
     tmp 
    on subscriber.msisdn=tmp.msisdn and tmp.row<=5 
+0

他正在使用MySQL,在MySQL中没有OVER/PARTITION – amenadiel 2014-11-21 12:00:48

+2

@nitubansal即使我写了相同的查询密集的排名......我认为他应该提及,他正在寻找mysql的结果也是他的问题标记为SQL和它可能是任何sql – 2014-11-21 12:06:07

+1

无处不在,写入的查询应该在sql或MySQL中,并且在方法中没有任何错误,并且可能对查找sql​​方法的人有用。 – 2014-11-21 12:07:23

2

我认为你可以做到这一点使用变量分配各行的行号,然后每个日期筛选的前5名。

SELECT s.name AS name, 
     s.gender AS gender, 
     s.msisdn, 
     ss.date, 
     ss.score 
FROM ( SELECT ss.msisdn, 
        ss.score, 
        @r:= CASE WHEN ss.Date = @d THEN @r + 1 ELSE 1 END AS RowNum, 
        @d:= ss.date AS winning_date 
      FROM subscriber_score AS ss 
        CROSS JOIN (SELECT @d:= '', @r:= 0) AS v 
      WHERE ss.date > '2014-10-10' 
      AND  ss.date < '2014-11-10' 
      ORDER BY ss.Date, ss.Score DESC 
     ) AS ss 
     INNER JOIN Subscriber AS s 
      ON s.msisdn = ss.msisdn 
WHERE ss.RowNum <= 5; 

Example on SQL Fiddle

+0

这是在MySQL中做到这一点的正确方式,但它可能需要一些微调,例如初始化@d和开始日期。 – amenadiel 2014-11-21 11:59:56

+0

谢谢,这看起来像。让我适应我的情况,稍后再告诉你。 – 2014-11-21 12:48:41