mysql 分組獲取前三條記錄

 

要求:編寫一個SQL,獲取部門工資前三高的員工。.net

員工表和部門表結構:排序

CREATE TABLE `employee` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255),
  `salary` decimal(10,2),
  `department_id` int(11),
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;ci

CREATE TABLE `department` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255),
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

員工表和部門表數據:get

INSERT INTO `employee`(`id`, `name`, `salary`, `department_id`) VALUES (1, 'Joe', 70000.00, 1);
INSERT INTO `employee`(`id`, `name`, `salary`, `department_id`) VALUES (2, 'Henry', 80000.00, 2);
INSERT INTO `employee`(`id`, `name`, `salary`, `department_id`) VALUES (3, 'Sam', 60000.00, 2);
INSERT INTO `employee`(`id`, `name`, `salary`, `department_id`) VALUES (4, 'Max', 90000.00, 1);
INSERT INTO `employee`(`id`, `name`, `salary`, `department_id`) VALUES (5, 'Janet', 69000.00, 1);
INSERT INTO `employee`(`id`, `name`, `salary`, `department_id`) VALUES (6, 'Randy', 85000.00, 1);
INSERT INTO `employee`(`id`, `name`, `salary`, `department_id`) VALUES (7, 'Eva', 85000.00, 1);class

INSERT INTO `department`(`id`, `name`) VALUES (1, 'IT');
INSERT INTO `department`(`id`, `name`) VALUES (2, 'Sales');

題庫的答案:變量

SELECT
    d.`name` AS '部門',
    e.`name` AS '員工',
    e.salary AS '工資' 
FROM
    employee e
    JOIN department d ON d.id = e.department_id 
WHERE
    (
    SELECT count(DISTINCT em.salary) FROM employee em WHERE em.salary > e.salary AND em.department_id = e.department_id
    ) < 3 
ORDER BY e.department_id, e.salary DESC

輸出結果以下:select

部門    員工    工資
IT    Max    90000
IT    Randy    85000
IT    Eva    85000
IT    Joe    70000
Sales    Henry    80000
Sales    Sam    60000
首先來理解一下上面的 SQL,當 < 3 的條件改成 = 0 時,即子表中相同部門沒有比主表工資高的員工,則取得工資最高的員工;當條件爲 = 1 時,表示子表中相同部門裏只有一個比主表工資高的員工,則取得工資第二高的員工;同理,條件 = 2 表示工資第三高的員工,因此工資前三高的員工的條件爲 < 3。im

經過結果能夠看到,第二名員工和第三名員工工資相同,被看成並列第二,並不會排擠掉第三名。若是咱們但願出現並列第二名時,第三名就變成第四名呢?能夠把 count(DISTINCT em.salary) 改爲 count(*)。數據

SELECT
    d.`name` AS '部門',
    e.`name` AS '員工',
    e.salary AS '工資' 
FROM
    employee e
    JOIN department d ON d.id = e.department_id 
WHERE
    (
    SELECT count(*) FROM employee em WHERE em.salary > e.salary AND em.department_id = e.department_id
    ) < 3 
ORDER BY e.department_id, e.salary DESC

輸出結果:查詢

部門    員工    工資
IT    Max    90000
IT    Randy    85000
IT    Eva    85000
Sales    Henry    80000
Sales    Sam    60000
上面的寫法中,當咱們取前兩名時,會獲得 IT 部門的第一名和兩個第二名的員工。若是咱們但願去掉並列的狀況,即就算工資相同也分爲不一樣名次呢?那能夠根據工資排序來增長多一個序號列,把 employee 表替換成下面這個子表:

SELECT (@i:=@i+1) AS rownum, es.* FROM employee es, (select @i:=0) ri ORDER BY es.salary
1
而後去查詢每一個部門工資前兩名的員工,這裏注意一下,兩個子表變量名須要不同:

SELECT
    d.`name` AS '部門',
    e.`name` AS '員工',
    e.salary AS '工資' 
FROM
    (SELECT (@i:=@i+1) AS rownum, es.* FROM employee es, (select @i:=0) ri ORDER BY es.salary) e
    JOIN department d ON d.id = e.department_id 
WHERE
    (
    SELECT count(*) FROM (SELECT (@j:=@j+1) AS rownum, es.* FROM employee es, (select @j:=0) rj ORDER BY es.salary) em WHERE em.rownum > e.rownum AND em.department_id = e.department_id
    ) < 2
ORDER BY e.department_id, e.salary DESC

結果以下:

部門    員工    工資 IT    Max    90000 IT    Randy    85000 Sales    Henry    80000 Sales    Sam    60000  ————————————————   

相關文章
相關標籤/搜索