2016-07-22 54 views
0

,所以我有这样的表中的数据排名:的mysql进行分组与领带

id  total group_id 
1897  738  1 
2489  716  2 
2325  715  3 
1788  702  2 
1707  699  3 
2400  688  3 
2668  682  2 
1373  666  1 
1494  666  1 
1564  660  1 
2699  659  1 
1307  648  4 
1720  645  4 
2176  644  1 
1454  644  4 
2385  639  3 
1001  634  2 
2099  634  4 
1006  632  1 
2587  630  3 
1955  624  3 
1827  624  4 
2505  623  4 
2062  621  3 
1003  618  1 
2286  615  4 
2722  609  4 

我怎么可以排名每组的IDS基于总,并给予同级别的时候有一搭?

我曾尝试下面这种解决方案,但它不走关系的照顾。

SELECT g1.admission_no 
, g1.total 
, g1.stream_id 
, COUNT(*) AS rn 
FROM ranktest AS g1 
    JOIN ranktest AS g2 
    ON (g2.total, g2.admission_no) >= (g1.total, g1.admission_no) 
    AND g1.stream_id = g2.stream_id 
    GROUP BY g1.admission_no 
    , g1.stream_id 
    , g1.total 
    ORDER BY g1.stream_id 
    , total ; 

预计

id  total group_id rank 
1897  738  1  1 
2489  716  2  1 
2325  715  3  1 
1788  702  2  2 
1707  699  3  2 
2400  688  3  3 
2668  682  2  3 
1373  666  1  2 
1494  666  1  2 
1564  660  1  3 
2699  659  1  4 
1307  648  4  1 
1720  645  4  2 
2176  644  1  4 
1454  644  4  3 
2385  639  3  4 
1001  634  2  4 
2099  634  4  4 
1006  632  1  5 
2587  630  3  5 
1955  624  3  6 
1827  624  4  5 
2505  623  4  6 
2062  621  3  6 
1003  618  1  6 
2286  615  4  7 
2722  609  4  8 
+0

[选择](http://dev.mysql.com/doc/refman/5.7/en/select.html)+ [聚集体](http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html)。我们不会为你写代码。你写代码,我们(也许)试着修复它。 –

+0

@MarcB我有这段代码使用连接,但ID没有照顾的关系,我不知道如何解决它 – GOA

+0

所以显示此代码。但是如果你想要关系,你需要额外的查询脚手架来检测关系并且拉出产生这些关系的记录。 –

回答

0

确保谷歌上搜索一个bit..not后,想出了这个答案是其最好的,但它适合我的情况:

SELECT id, group_id, total, 
    @std:=CASE WHEN @grp <> group_id THEN concat(left(@grp:=group_id, 0), 1) ELSE if(@prev=total,@std,@std+1) END AS rn,@prev:=total 
FROM 
    (SELECT @std:= -1) s, 
(SELECT @grp:= -1,@prev:=null) c, 
(SELECT * 
    FROM table 
    ORDER BY group_id, total desc 
) s 
2

如果原来的顺序是不是很重要你可以从这里开始:

http://sqlfiddle.com/#!9/a15a2/10

SELECT 
    ranktest.*, 
    IF(@rank IS NULL,@rank:=1, IF(@prev!=group_id,@rank:=1,@rank:[email protected]+1)) rank, 
    @prev:=group_id 
FROM ranktest 
ORDER BY group_id, total 

但请记住,这是不是从性能的角度来看非常高效的查询。

1

从有权User-Defined Variables MySQL手册页:

在下面的语句,你 可能会认为MySQL将评估@a第一,然后做一个 分配第二:

SELECT @a, @a:[email protected]+1, ...; 

然而,涉及用户 变量的表达式的评估顺序未定义。

这就是为什么这么几个人正确,安全地写这些的答案。目标不是一次达到预期的结果,而是要在实际环境中一次又一次地使用最佳实践和保证结果。

如果你不读Obligatory Doc,并执行它,你的结果不能保证。有没有偷懒的办法来做到这一点,一个不应该甚至懒得:对

select id,total,group_id,rank 
from 
( select id,total,group_id, 
    @rn:=if( [email protected]_grp, greatest(@grp_rank:=1,0), 
     if([email protected]_grp_total,@grp_rank,greatest(@grp_rank:[email protected]_rank+1,0))) as rank, 
    @curr_grp:=group_id, 
    @prev_grp_total:=total 
    from trans01 
    cross join (select @grp_rank:=0,@curr_grp:=0,@prev_grp_total:=-1) xParams 
    order by group_id,total desc 
)xDerived; 

+------+-------+----------+------+ 
| id | total | group_id | rank | 
+------+-------+----------+------+ 
| 1897 | 738 |  1 | 1 | 
| 1373 | 666 |  1 | 2 | 
| 1494 | 666 |  1 | 2 | 
| 1564 | 660 |  1 | 3 | 
| 2699 | 659 |  1 | 4 | 
| 2176 | 644 |  1 | 5 | 
| 1006 | 632 |  1 | 6 | 
| 1003 | 618 |  1 | 7 | 

| 2489 | 716 |  2 | 1 | 
| 1788 | 702 |  2 | 2 | 
| 2668 | 682 |  2 | 3 | 
| 1001 | 634 |  2 | 4 | 

| 2325 | 715 |  3 | 1 | 
| 1707 | 699 |  3 | 2 | 
| 2400 | 688 |  3 | 3 | 
| 2385 | 639 |  3 | 4 | 
| 2587 | 630 |  3 | 5 | 
| 1955 | 624 |  3 | 6 | 
| 2062 | 621 |  3 | 7 | 

| 1307 | 648 |  4 | 1 | 
| 1720 | 645 |  4 | 2 | 
| 1454 | 644 |  4 | 3 | 
| 2099 | 634 |  4 | 4 | 
| 1827 | 624 |  4 | 5 | 
| 2505 | 623 |  4 | 6 | 
| 2286 | 615 |  4 | 7 | 
| 2722 | 609 |  4 | 8 | 
+------+-------+----------+------+ 
+0

我会再次敏锐地读到它。 – GOA

+0

诀窍在于将var嵌入到'least()','most()'或'coalesce()'中。它可能看起来很荒谬,说,给我最大的9或0,但有一种方法来疯狂。 – Drew

+0

它也可以工作 – GOA