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
最終結果