sql中筛选第一条记录

简介: 问题描述我们现在有一张表titles,共有4个字段,分别是emp_no(员工编号),title(职位),from_date(起始时间),to_date(结束时间),记录的是员工在某个时间段内职位名称,因为会存在升职,转岗之类的,里面emp_no可能会对应多个职位,我们现在要取到所有员工最近的职位信息,包括离职员工。

问题描述

我们现在有一张表titles,共有4个字段,分别是emp_no(员工编号),title(职位),from_date(起始时间),to_date(结束时间),记录的是员工在某个时间段内职位名称,因为会存在升职,转岗之类的,里面emp_no可能会对应多个职位,我们现在要取到所有员工最近的职位信息,包括离职员工。


本文介绍两种方法去实现结果:

方法一

嵌套一个group by+max()子查询获取最近的职位信息。

思路
  1. 通过对emp_no分组取每个emp_no对应的最大的from_date;
SELECT
    emp_no,
    max( from_date ) AS max_date 
FROM
    titles 
GROUP BY
    emp_no

结果如下:


img_34c21cfbf299d74008a0fbf7e838eb53.png
image.png
  1. 通过查询出来的最大的from_date取筛选最近的的一条职位信息。
SELECT
    t.emp_no,
    t.title 
FROM
    titles t
    LEFT JOIN ( SELECT emp_no, max( from_date ) AS max_date FROM titles GROUP BY emp_no ) et 
ON t.emp_no = et.emp_no AND t.from_date = et.max_date

结果如下:


img_fb32f2a1c42e48579b1bbc9b12281204.png
image.png

方法二

通过rank over partition by函数实现,这个目前是Oracle独有的函数,如果你用的是mysql或者sql server就没办法使用了。

语法

功能:在原有表的基础上加上一个根据条件排序的伪列。

SELECT
    *,
     RANK() OVER (PARTITION BY emp_no ORDER BY from_date DESC) AS rank
FROM
    titles

RANK() OVER (PARTITION BY emp_no ORDER BY from_date DESC) AS rank表示把表根据emp_no进行分区,然后在分区内根据from_date进行降序排列,排序结果生成一列命名为rank。
我们之前在问题里面提到了一个emp_no会对应多条职位信息,然后对于每个emp_no的记录进行一个降序排列,接下来我们只需要把上面的结果当成一个子查询然后筛选rank = 1 就好了。

完整代码如下
SELECT
    * 
FROM
    ( SELECT *, RANK ( ) OVER ( PARTITION BY emp_no ORDER BY from_date DESC ) AS rank FROM titles ) r 
WHERE
    r.rank = '1'

由于我笔记本只装了mysql的环境,所以就没法给各位展示效果了。


综上,如果各位目前使用的是Oracle,推荐各位使用方法二:

  • 方法二容错率高,如果titles表里面有两条记录emp_no和from_date都是一样的,方法一就会报错了,单条子查询返回多行;
  • 方法二还可以实现取第二条,第三条。。。的记录,方法一只有一个最大或者最小可供选择。

peace~

目录
相关文章
|
6月前
|
SQL
SQL 的 AND、OR 和 NOT 运算符:条件筛选的高级用法
SQL的AND运算符用于根据多个条件筛选记录,确保所有条件都为TRUE才返回记录。下面是AND运算符的基本语法:
125 1
|
3月前
|
SQL 数据处理 数据库
SQL进阶之路:深入解析数据更新与删除技巧——掌握批量操作、条件筛选、子查询和事务处理,提升数据库维护效率与准确性
【8月更文挑战第31天】在数据库管理和应用开发中,数据的更新和删除至关重要,直接影响数据准确性、一致性和性能。本文通过具体案例,深入解析SQL中的高级更新(UPDATE)和删除(DELETE)技巧,包括批量更新、基于条件的删除以及使用子查询和事务处理复杂场景等,帮助读者提升数据处理能力。掌握这些技巧能够有效提高数据库性能并确保数据一致性。
76 0
|
6月前
|
消息中间件 SQL RocketMQ
RocketMQ-初体验RocketMQ(10)-过滤消息_SQL92表达式筛选消息
RocketMQ-初体验RocketMQ(10)-过滤消息_SQL92表达式筛选消息
141 0
|
6月前
|
SQL API 数据库
在Python中获取筛选后的SQL数据行数
在Python中获取筛选后的SQL数据行数
62 1
|
6月前
|
SQL Oracle 关系型数据库
Greenplum【SQL 01】通过 timestamp 类型字段值实现数据的日期时段筛选+时间时段筛选(跨天时段及不跨天时段SQL详情)
Greenplum【SQL 01】通过 timestamp 类型字段值实现数据的日期时段筛选+时间时段筛选(跨天时段及不跨天时段SQL详情)
87 0
|
6月前
|
SQL 数据库
SQL HAVING 子句详解:在 GROUP BY 中更灵活的条件筛选
HAVING子句被添加到SQL中,因为WHERE关键字不能与聚合函数一起使用。
212 0
|
SQL 大数据 开发者
电商项目之商家用户交互记录宽表 SQL 实现|学习笔记
快速学习电商项目之商家用户交互记录宽表 SQL 实现
电商项目之商家用户交互记录宽表 SQL 实现|学习笔记
|
SQL 数据库
Navicat筛选出所需数据并导成SQL脚本文件
Navicat筛选出所需数据并导成SQL脚本文件
778 0
Navicat筛选出所需数据并导成SQL脚本文件
|
SQL 索引
sql做题第十六天(删除记录篇)
• 扩展:在 delete 后加 limit 是个好习惯。原因如下: • 1,delete from 是全表查找的,如果加上limit 时,删除指定的条数后,就会return了。效率提高不少。 • 2,降低写错 SQL 的代价,即使删错了,例如limit 100,也就删除了100条数据,也能通过binlog找回数据 • 3,避免长事务,delete执行时,涉及的行是会加锁,如果删除的数据量大,那业务功能都要不能用了 • 4,加锁都是基于索引的,如果查询字段没有加索引,那会扫描到主键索引上,那么就算查询出来的只有一条记录,也会锁表 • 5,delete数据量大时,容易占用cpu,导致越删除越慢
|
SQL 关系型数据库 MySQL
sql做题第十五天(更新记录篇)
第三十七例:更新记录(2) • 题目地址:更新记录(二)牛客题霸牛客网 (nowcoder.com) • 初始化数据: