• mysql中分组获取前三条记录的方法


    转自:  https://www.yisu.com/zixun/595682.html

    这篇文章主要介绍mysql中分组获取前三条记录的方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

    要求:编写一个SQL,获取部门工资前三高的员工。

    员工表和部门表结构:

    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;

    CREATE TABLE `department` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(255),
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
    员工表和部门表数据:

    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);

    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
    输出结果如下:

    部门    员工    工资
    IT    Max    90000
    IT    Randy    85000
    IT    Eva    85000
    IT    Joe    70000
    Sales    Henry    80000
    Sales    Sam    60000
    首先来理解一下上面的 SQL,当 < 3 的条件改为 = 0 时,即子表中相同部门没有比主表工资高的员工,则取得工资最高的员工;当条件为 = 1 时,表示子表中相同部门里只有一个比主表工资高的员工,则取得工资第二高的员工;同理,条件 = 2 表示工资第三高的员工,所以工资前三高的员工的条件为 < 3。

    通过结果可以看到,第二名员工和第三名员工工资相同,被当作并列第二,并不会排挤掉第三名。如果我们希望出现并列第二名时,第三名就变成第四名呢?可以把 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

  • 相关阅读:
    .NET Core 5
    2018.6.5号----TeamViewer12 13 非商用出现商用限制怎么解决
    第:九课:SQL数据库___超级列表框与数据库的组合修改
    第八课:SQL数据库插入数据和更新数据
    第七课:数据库表的创建
    第六课:数据库的基本工具
    第五课: 模拟器的绑定与文本发送应用.exe
    第四课:APK的一些操作
    第三课:模拟器里安装手游APK安装
    第二课: 雷电模拟器的多开和打开
  • 原文地址:https://www.cnblogs.com/maidongdong/p/16377258.html
Copyright © 2020-2023  润新知