1. 程式人生 > >mysql組內排序

mysql組內排序

比如說要獲取班級的前3名,oracle 可以用 over partition by 來做。mysql就可以用GROUP_CONCAT + GROUP BY + substring_index實現。

考試表

DROP TABLE IF EXISTS test;
CREATE TABLE test (
id int(11) DEFAULT NULL,
name varchar(20) DEFAULT NULL,
score int(11) DEFAULT NULL,
class char(12) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

插入資料

INSERT INTO test (id, name, score, class) VALUES (‘1’, ‘Bobdd’, ‘25’, ‘1’);
INSERT INTO test (id, name, score, class) VALUES (‘2’, ‘xx’, ‘20’, ‘2’);
INSERT INTO test (id, name, score, class) VALUES (‘3’, ‘Jack’, ‘30’, ‘2’);
INSERT INTO test (id, name, score, class) VALUES (‘4’, ‘Bill’, ‘32’, ‘4’);
INSERT INTO test

(id, name, score, class) VALUES (‘5’, ‘Nick’, ‘22’, ‘3’);
INSERT INTO test (id, name, score, class) VALUES (‘6’, ‘Kathy’, ‘18’, ‘3’);
INSERT INTO test (id, name, score, class) VALUES (‘7’, ‘Steve’, ‘36’, ‘3’);
INSERT INTO test (id, name, score, class) VALUES (‘8’, ‘Anne’, ‘25’, ‘2’);
INSERT INTO test
(id, name, score, class) VALUES (‘9’, ‘Kathy’, ‘18’, ‘2’);
INSERT INTO test (id, name, score, class) VALUES (‘11’, ‘Bob1’, ‘25’, ‘3’);
INSERT INTO test (id, name, score, class) VALUES (‘12’, ‘Jane1’, ‘20’, ‘1’);
INSERT INTO test (id, name, score, class) VALUES (‘13’, ‘Jack1’, ‘30’, ‘1’);
INSERT INTO test (id, name, score, class) VALUES (‘14’, ‘Bill1’, ‘32’, ‘1’);
INSERT INTO test (id, name, score, class) VALUES (‘15’, ‘Nick1’, ‘22’, ‘4’);
INSERT INTO test (id, name, score, class) VALUES (‘16’, ‘Kathy1’, ‘18’, ‘4’);
INSERT INTO test (id, name, score, class) VALUES (‘17’, ‘Steve1’, ‘36’, ‘4’);
INSERT INTO test (id, name, score, class) VALUES (‘18’, ‘Anne1’, ‘25’, ‘1’);
INSERT INTO test (id, name, score, class) VALUES (‘19’, ‘Kathy1’, ‘18’, ‘2’);

運用group_concat + GROUP BY 分組 獲取前3名

select GROUP_CONCAT(t1.id) as ids from (
SELECT t.class, substring_index(GROUP_CONCAT(t.id ORDER BY t.score desc),’,’,3) as id from
test t GROUP BY t.class
)t1

得到

注意 是t.id ORDER BY t.score desc 分數從高到低。

上面的語句只是獲取到總的id。但是轉換為列不太好弄。可以拆分用union all 來搞。

獲取第一名

SELECT t.class, substring_index(GROUP_CONCAT(t.id ORDER BY t.score desc),’,’,1) as id from
test t GROUP BY t.class

union all

– 第二名
SELECT t.class, substring_index(substring_index(GROUP_CONCAT(t.id ORDER BY t.score desc),’,’,2),’,’,-1) as id from
test t GROUP BY t.class

union all

– 第三名
SELECT t.class, substring_index(substring_index(GROUP_CONCAT(t.id ORDER BY t.score desc),’,’,3),’,’,-1) as id from
test t GROUP BY t.class

好了到現在 已經獲取到了一個list

用 in 來完成最後的步驟

SELECT class,score,name FROM test where id in(
SELECT id from
(SELECT t.class, substring_index(GROUP_CONCAT(t.id ORDER BY t.score desc),’,’,1) as id from
test t GROUP BY t.class
union all
SELECT t.class, substring_index(substring_index(GROUP_CONCAT(t.id ORDER BY t.score desc),’,’,2),’,’,-1) as id from
test t GROUP BY t.class
union all
SELECT t.class, substring_index(substring_index(GROUP_CONCAT(t.id ORDER BY t.score desc),’,’,3),’,’,-1) as id from
test t GROUP BY t.class) t2
) ORDER BY class asc,score desc

最終結果