如何为MySQL中的唯一值生成唯一编号?

时间:2014-03-02 07:04:23

标签: php mysql

我无法为唯一值创建唯一数字。我在MySQL表中有25行我想在其上分配排名。假设10个用户获得相同的值:我想为它们分配相同的数字,其余的将是唯一的。我有以下MySQL查询:

(SELECT std_login_id AS ID, STD_NAME, TOTAL_MARKS, (@rnk := @rnk + 1) AS RANK FROM 
(SELECT ob.std_login_id, SUM(ob.marks_obtain) AS TOTAL_MARKS, std.student_name AS STD_NAME
    FROM exam_marks_obt ob
    JOIN ac_std_preadmission STD ON ob.std_login_id = std.std_login_id
    JOIN adm_class AS cl ON cl.class_id = std.class_id
    JOIN adm_section se ON se.section_id=std.section_id
    WHERE cl.class_id = 1 AND se.section_id = 1
    GROUP BY ob.std_login_id
    ORDER BY ABS(SUM(ob.marks_obtain)) DESC)
ob CROSS JOIN (SELECT @rnk := 0) AS flyRank )
;

结果如下:

ID | STD_NAME | TOTAL_MARKS | RANK
1  | name1    | 250         | 1
2  | name2    | 250         | 2
3  | name3    | 200         | 3
4  | name4    | 200         | 4
5  | name5    | 150         | 5
6  | name6    | 150         | 6

我想生成Rank这样的250 => 1,200 => 2,150 => 3。请告诉我在代码中我可以做些什么来产生这个等级?

2 个答案:

答案 0 :(得分:2)

我创建了一个测试表来模拟聚合标记的内部选择。然后,允许按列顺序切换,我尝试简单地使用您的方法,因为您已经在查询中使用变量。

SELECT std_login_id AS ID, STD_NAME,
       (@rnk := IF(@track = TOTAL_MARKS , @rnk, @rnk + 1)) AS RANK,
       (@track:= TOTAL_MARKS) as TOTAL_MARKS
  FROM ( select *
           from testtable
       ORDER BY total_marks DESC) ob
CROSS JOIN (SELECT @rnk := 0, @track := 0) AS starter;

我相信这会产生你想要的东西。可能有更好的方法,但现在已经很晚了,所以我会选择它。 : - )

如果您想快速测试,只需粘贴并转到:

create table testtable (
    std_login_id int(11) primary key auto_increment,
    total_marks int(11),
    std_name  varchar(10)
);

insert into testtable (total_marks,std_name) values (10,'name1');
insert into testtable (total_marks,std_name) values (15,'name2');
insert into testtable (total_marks,std_name) values (15,'name3');
insert into testtable (total_marks,std_name) values (40,'name4');
insert into testtable (total_marks,std_name) values (50,'name5');
insert into testtable (total_marks,std_name) values (15,'name6');
insert into testtable (total_marks,std_name) values (10,'name7');
insert into testtable (total_marks,std_name) values (20,'name8');
insert into testtable (total_marks,std_name) values (10,'name9');
insert into testtable (total_marks,std_name) values (10,'name10');
insert into testtable (total_marks,std_name) values (50,'name11');
insert into testtable (total_marks,std_name) values (10,'name12');
insert into testtable (total_marks,std_name) values (25,'name13');
insert into testtable (total_marks,std_name) values (10,'name14');
insert into testtable (total_marks,std_name) values (50,'name15');
insert into testtable (total_marks,std_name) values (10,'name16');
insert into testtable (total_marks,std_name) values (50,'name17');
insert into testtable (total_marks,std_name) values (20,'name18');
insert into testtable (total_marks,std_name) values (40,'name19');
insert into testtable (total_marks,std_name) values (30,'name20');

答案 1 :(得分:1)

您可以使用此查询,从而产生具有正确排名的总分数。

(SELECT TOTAL_MARKS, (@rnk := @rnk + 1) AS RANK 
FROM 
(
    (SELECT distinct(TOTAL_MARKS) AS TOTAL_MARKS 
    FROM
        (SELECT SUM(ob.marks_obtain) AS TOTAL_MARKS
        FROM exam_marks_obt ob
        JOIN ac_std_preadmission STD ON ob.std_login_id = std.std_login_id
        JOIN adm_class AS cl ON cl.class_id = std.class_id
        JOIN adm_section se ON se.section_id=std.section_id
        WHERE cl.class_id = 1 AND se.section_id = 1
        GROUP BY ob.std_login_id
        ORDER BY ABS(SUM(ob.marks_obtain)) DESC)) ob 
    CROSS JOIN (SELECT @rnk := 0) AS flyRank ))

这样的事情:

| TOTAL_MARKS | RANK
| 250         | 1
| 200         | 2
| 150         | 3

现在,您可以使用STD_NAME s及其TOTAL_MARK s表格加入。