sql查詢每組前幾條記錄
阿新 • • 發佈:2018-12-14
首先建立測試資料
CREATE TABLE `t2` ( `id` int(11) NOT NULL, `gid` char(1) DEFAULT NULL, `col1` int(11) DEFAULT NULL, `col2` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; INSERT INTO `t2` VALUES ('1', 'A', '31', '6'); INSERT INTO `t2` VALUES ('2', 'B', '25', '83'); INSERT INTO `t2` VALUES ('3', 'C', '76', '21'); INSERT INTO `t2` VALUES ('4', 'D', '63', '56'); INSERT INTO `t2` VALUES ('5', 'E', '3', '17'); INSERT INTO `t2` VALUES ('6', 'A', '29', '97'); INSERT INTO `t2` VALUES ('7', 'B', '88', '63'); INSERT INTO `t2` VALUES ('8', 'C', '16', '22'); INSERT INTO `t2` VALUES ('9', 'D', '25', '43'); INSERT INTO `t2` VALUES ('10', 'E', '45', '28'); INSERT INTO `t2` VALUES ('11', 'A', '2', '78'); INSERT INTO `t2` VALUES ('12', 'B', '30', '79'); INSERT INTO `t2` VALUES ('13', 'C', '96', '73'); INSERT INTO `t2` VALUES ('14', 'D', '37', '40'); INSERT INTO `t2` VALUES ('15', 'E', '14', '86'); INSERT INTO `t2` VALUES ('16', 'A', '32', '67'); INSERT INTO `t2` VALUES ('17', 'B', '84', '38'); INSERT INTO `t2` VALUES ('18', 'C', '27', '9'); INSERT INTO `t2` VALUES ('19', 'D', '31', '21'); INSERT INTO `t2` VALUES ('20', 'E', '80', '63'); INSERT INTO `t2` VALUES ('21', 'A', '89', '9'); INSERT INTO `t2` VALUES ('22', 'B', '15', '90'); INSERT INTO `t2` VALUES ('23', 'C', '46', '84'); INSERT INTO `t2` VALUES ('24', 'D', '54', '79'); INSERT INTO `t2` VALUES ('25', 'E', '85', '64'); INSERT INTO `t2` VALUES ('26', 'A', '87', '13'); INSERT INTO `t2` VALUES ('27', 'B', '40', '90'); INSERT INTO `t2` VALUES ('28', 'C', '34', '90'); INSERT INTO `t2` VALUES ('29', 'D', '63', '8'); INSERT INTO `t2` VALUES ('30', 'E', '66', '40'); INSERT INTO `t2` VALUES ('31', 'A', '83', '49'); INSERT INTO `t2` VALUES ('32', 'B', '4', '90'); INSERT INTO `t2` VALUES ('33', 'C', '81', '7'); INSERT INTO `t2` VALUES ('34', 'D', '11', '12'); INSERT INTO `t2` VALUES ('35', 'E', '85', '10'); INSERT INTO `t2` VALUES ('36', 'A', '39', '75'); INSERT INTO `t2` VALUES ('37', 'B', '22', '90'); INSERT INTO `t2` VALUES ('38', 'C', '76', '67'); INSERT INTO `t2` VALUES ('39', 'D', '20', '11'); INSERT INTO `t2` VALUES ('40', 'E', '81', '36');
網上大多數例子都是用類似如下寫法,其實是錯誤的:
select d.Name as Department, e.Name as Employee, e.Salary as Salary from Employee as e inner join Department as d on e.DepartmentId = d.Id where (select count(distinct(e1.Salary)) from Employee as e1 where e1.DepartmentId = e.DepartmentId and e1.Salary > e.Salary) < 3 order by e.Salary desc;
這個sql的原理是根據排序欄位,逐個分數比較,取總數小於要取的排名數,當排序欄位可以重複時,排序欄位前一個出現重複時會導致該分組無記錄或是少記錄
oracle或MySQL(版本在8.0以上)在mysql(8.0.12)上測試通過:
SELECT * FROM ( SELECT s.*, row_number() over ( PARTITION BY gid ORDER BY col2 DESC ) AS class_rank FROM t2 s ) d WHERE d.class_rank <= 2 order by gid,col2 desc
mysql低版本,使用變數的方式(已測試):
select * from
(
select
@rows:=CASE when @ids=a.gid then @rows+1 else 1 end as groupRow,
@ids:=a.gid as gid,
a.col2
from t2 a ,( select @rows:=1, @ids:='') b
ORDER BY a.gid , a.col2 desc
) w
where w.groupRow <=2
如有問題麻煩提出來共同解決~