2013-07-02 56 views
0

我有一个包含日期,ID和值的表,每个日期约有1000个id行。我需要按日期计算每行的百分位数。我将以下代码用于单个日期的百分比排名,但是具有超过10年的日常数据,这是非常低效的以按日期运行。似乎它应该能够在MySQL中制定,但我无法使其工作。mysql百分位按组排列

Date ID Value 
date1 01 -7.2 
date1 02  0.6 
date2 01  1.2 
date2 02  3.8 

SELECT c.id, c.value, ROUND((
(@rank - rank)/@rank) *100, 2) AS rank 
FROM (
SELECT * , @prev := @curr , @curr := a.value, 
@nxtRnk := @nxtRnk + 1, 
@rank := IF(@prev = @curr , @rank , @nxtRnk) AS rank 
FROM (
SELECT id, value 
FROM temp 
WHERE date = '2013-06-28' 
) AS a, (

SELECT @curr := NULL , @prev := NULL , @rank :=0, @nxtRnk :=0 
) AS b 
ORDER BY value DESC 
) AS c 

所以基本上我想SELECT DISTINCT(日期),然后每个日期执行上述SELECT,这是由INSERT INTO preceeded表2(...),以将结果写入表2。

感谢您的帮助, 休

回答

0

我终于通过使用临时表制定可接受的解决方案。也许不是最佳的解决方案,但它在一百万+记录表格上运行约5秒。

我的临时表(t1)包含日期和日期的行数。

第三选择上述变更为 SELECT t1.date,t1.cnt,ID,值从T1 LEFT JOIN温度ON(t1.date = temp.date)

此外,在第一计算上面的SELECT更改为使用c.cnt而不是@rank,并且创建了@prevDate变量来重置日期更改时的等级计数。

感谢任何看着这个并试图解决问题的人。

0

我试图解决这个很长一段时间,然后我找到了以下答案。老实说,辉煌。即使对于大桌子也是相当快的(我使用它的桌子包含大约5密耳的记录并且需要几秒钟)。

SELECT 
    CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(field_name ORDER BY 
    field_name SEPARATOR ','), ',', 95/100 * COUNT(*) + 1), ',', -1) AS DECIMAL) 
    AS 95th Per 
FROM table_name; 

正如你可以想象的只是用你的表和列的名称替换table_name和field_name。

如需进一步信息查询Roland Bouman的原始帖子