【SQL开发实战技巧】系列(二十一):数据仓库中时间类型操作(进阶)识别重叠的日期范围,按指定10分钟时间间隔汇总数据

简介: 如何识别重叠的日期范围、日期出现次数、确定当前记录和下一条记录之间相差的天数【SQL开发实战技巧】这一系列博主当作复习旧知识来进行写作,毕竟SQL开发在数据分析场景非常重要且基础,面试也会经常问SQL开发和调优经验,相信当我写完这一系列文章,也能再有所收获,未来面对SQL面试也能游刃有余~。例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

前言

本篇文章讲解的主要内容是:如何识别重叠的日期范围、日期出现次数、确定当前记录和下一条记录之间相差的天数
【SQL开发实战技巧】这一系列博主当作复习旧知识来进行写作,毕竟SQL开发在数据分析场景非常重要且基础,面试也会经常问SQL开发和调优经验,相信当我写完这一系列文章,也能再有所收获,未来面对SQL面试也能游刃有余~。


一、识别重叠的日期范围

下面是一个有关工程的明细数据:

create or replace view zyd as 
SELECT 7782 empno,'CLARK'  as ename,1 as proj_id,date'2023-06-16' proj_start,date'2023-06-18' proj_end from dual union all
SELECT 7782 empno,'CLARK'  as ename,4 as proj_id,date'2023-06-19' proj_start,date'2023-06-24' proj_end from dual union all
SELECT 7782 empno,'CLARK'  as ename,7 as proj_id,date'2023-06-22' proj_start,date'2023-06-25' proj_end from dual union all
SELECT 7782 empno,'CLARK'  as ename,10 as proj_id,date'2023-06-25' proj_start,date'2023-06-28' proj_end from dual union all
SELECT 7782 empno,'CLARK'  as ename,13 as proj_id,date'2023-06-28' proj_start,date'2023-07-02' proj_end from dual union all
SELECT 7839 empno,'KING'   as ename,2 as proj_id,date'2023-06-17' proj_start,date'2023-06-21' proj_end from dual union all
SELECT 7839 empno,'KING'   as ename,8 as proj_id,date'2023-06-23' proj_start,date'2023-06-25' proj_end from dual union all
SELECT 7839 empno,'KING'   as ename,14 as proj_id,date'2023-06-29' proj_start,date'2023-06-30' proj_end from dual union all
SELECT 7839 empno,'KING'   as ename,11 as proj_id,date'2023-06-26' proj_start,date'2023-06-27' proj_end from dual union all
SELECT 7839 empno,'KING'   as ename,5 as proj_id,date'2023-06-20' proj_start,date'2023-06-24' proj_end from dual union all
SELECT 7934 empno,'MILLER' as ename,3 as proj_id,date'2023-06-18' proj_start,date'2023-06-22' proj_end from dual union all
SELECT 7934 empno,'MILLER' as ename,12 as proj_id,date'2023-06-27' proj_start,date'2023-06-28' proj_end from dual union all
SELECT 7934 empno,'MILLER' as ename,15 as proj_id,date'2023-06-30' proj_start,date'2023-07-03' proj_end from dual union all
SELECT 7934 empno,'MILLER' as ename,9 as proj_id,date'2023-06-24' proj_start,date'2023-06-27' proj_end from dual union all
SELECT 7934 empno,'MILLER' as ename,6 as proj_id,date'2023-06-21' proj_start,date'2023-06-23' proj_end from dual;

select * from zyd;

     EMPNO ENAME     PROJ_ID PROJ_START  PROJ_END
---------- ------ ---------- ----------- -----------
      7782 CLARK           1 2023-6-16   2023-6-18
      7782 CLARK           4 2023-6-19   2023-6-24
      7782 CLARK           7 2023-6-22   2023-6-25
      7782 CLARK          10 2023-6-25   2023-6-28
      7782 CLARK          13 2023-6-28   2023-7-2
      7839 KING            2 2023-6-17   2023-6-21
      7839 KING            8 2023-6-23   2023-6-25
      7839 KING           14 2023-6-29   2023-6-30
      7839 KING           11 2023-6-26   2023-6-27
      7839 KING            5 2023-6-20   2023-6-24
      7934 MILLER          3 2023-6-18   2023-6-22
      7934 MILLER         12 2023-6-27   2023-6-28
      7934 MILLER         15 2023-6-30   2023-7-3
      7934 MILLER          9 2023-6-24   2023-6-27
      7934 MILLER          6 2023-6-21   2023-6-23

15 rows selected

通过数据可以看到,有很多员工在旧的工程结束之前就开始了新的工程(如员工 7782 的工程4结束日期是6月24日,而工程7开始日期是6月22日),现要求返回这些工程时间重复的数据。
前面介绍了Oracle中有两个分析函数LAGLEAD,分别用于访问结果集中的前一行和后一行。我们可以用分析函数LAG取得员工各自的上一个工程的结束日期及工程号,然后与当前工程相比较。

  • 1、取信息
SQL> select empno,
  2         ename,
  3         proj_id as 工程号,
  4         proj_start as 开始日期,
  5         proj_end as 结束日期,
  6         lag(proj_end) over(partition by empno order by proj_start) as 上一工程结束日期,
  7         lag(proj_id) over(partition by empno order by proj_start) as 上一工程号
  8    from zyd;

     EMPNO ENAME         工程号 开始日期    结束日期    上一工程结束日期      上一工程号
---------- ------ ---------- ----------- ----------- ----------- ----------
      7782 CLARK           1 2023-6-16   2023-6-18               
      7782 CLARK           4 2023-6-19   2023-6-24   2023-6-18            1
      7782 CLARK           7 2023-6-22   2023-6-25   2023-6-24            4
      7782 CLARK          10 2023-6-25   2023-6-28   2023-6-25            7
      7782 CLARK          13 2023-6-28   2023-7-2    2023-6-28           10
      7839 KING            2 2023-6-17   2023-6-21               
      7839 KING            5 2023-6-20   2023-6-24   2023-6-21            2
      7839 KING            8 2023-6-23   2023-6-25   2023-6-24            5
      7839 KING           11 2023-6-26   2023-6-27   2023-6-25            8
      7839 KING           14 2023-6-29   2023-6-30   2023-6-27           11
      7934 MILLER          3 2023-6-18   2023-6-22               
      7934 MILLER          6 2023-6-21   2023-6-23   2023-6-22            3
      7934 MILLER          9 2023-6-24   2023-6-27   2023-6-23            6
      7934 MILLER         12 2023-6-27   2023-6-28   2023-6-27            9
      7934 MILLER         15 2023-6-30   2023-7-3    2023-6-28           12

15 rows selected



这里增加了partition by empno这样就可以对数据分组进行分析,不同的empno之间互不影响。
  • 2、比较
SQL> with t as
  2   (select empno,
  3           ename,
  4           proj_id as 工程号,
  5           proj_start as 开始日期,
  6           proj_end as 结束日期,
  7           lag(proj_end) over(partition by empno order by proj_start) as 上一工程结束日期,
  8           lag(proj_id) over(partition by empno order by proj_start) as 上一工程号
  9      from zyd)
 10  select t.empno,
 11         t.ename,
 12         t.工程号,
 13         t.开始日期,
 14         t.结束日期,
 15         case
 16           when 上一工程结束日期 >= 开始日期 then
 17            '工程' || lpad(工程号, 2, '0') || '与工程' || lpad(上一工程号, 2, '0') || '重复'
 18         end as 描述
 19    from t;

     EMPNO ENAME         工程号 开始日期    结束日期    描述
---------- ------ ---------- ----------- ----------- --------------------------------------------------------------------------------
      7782 CLARK           1 2023-6-16   2023-6-18   
      7782 CLARK           4 2023-6-19   2023-6-24   
      7782 CLARK           7 2023-6-22   2023-6-25   工程07与工程04重复
      7782 CLARK          10 2023-6-25   2023-6-28   工程10与工程07重复
      7782 CLARK          13 2023-6-28   2023-7-2    工程13与工程10重复
      7839 KING            2 2023-6-17   2023-6-21   
      7839 KING            5 2023-6-20   2023-6-24   工程05与工程02重复
      7839 KING            8 2023-6-23   2023-6-25   工程08与工程05重复
      7839 KING           11 2023-6-26   2023-6-27   
      7839 KING           14 2023-6-29   2023-6-30   
      7934 MILLER          3 2023-6-18   2023-6-22   
      7934 MILLER          6 2023-6-21   2023-6-23   工程06与工程03重复
      7934 MILLER          9 2023-6-24   2023-6-27   
      7934 MILLER         12 2023-6-27   2023-6-28   工程12与工程09重复
      7934 MILLER         15 2023-6-30   2023-7-3    

15 rows selected

如果只想看重复数据,直接加个过滤就行啦!!!

二、按指定间隔汇总数据

现在有个需求:按指定的时间间隔(10分钟)汇总数据,分别汇总至0分、10分、20分、30分等。
我这里用v$sql表来当作案例数据,先看下这里的部分数据:

select a.LAST_ACTIVE_TIME from v$sql a where rownum<=5;
LAST_ACTIVE_TIME
----------------
2023-2-13 22:14:27
2023-2-15 3:00:59
2023-2-7 1:05:29
2023-2-8 1:05:30
2023-2-15 15:59:03

我们一步步来。

  • 1、截取数据到分钟,并提取分钟信息
select sql_id,trunc(a.LAST_ACTIVE_TIME,'mi') as tim,to_char(a.LAST_ACTIVE_TIME,'mi') as mi  from v$sql a where sql_id='gcsnqzu9q0004'
SQL_ID    TIM    MI
gcsnqzu9q0004    2023-2-13 22:14:00    14

2、对14和10取余
SQL> select mod(14,10) from dual;

MOD(14,10)
----------
         4

SQL> 
  • 2、对比上面结果,我们可以知道如果想计算整10分钟的间隔,那就直接用MI-MOD(14,10)就算出来这个分钟对应在整十的哪个范围了。
select sql_id,
       trunc(a.LAST_ACTIVE_TIME, 'mi') as tim,
       to_char(a.LAST_ACTIVE_TIME, 'mi') as mi,
       to_char(a.LAST_ACTIVE_TIME, 'mi') -
       mod(to_char(a.LAST_ACTIVE_TIME, 'mi'), 10) as new_mi
  from v$sql a
 where sql_id = 'gcsnqzu9q0004';
SQL_ID    TIM    MI    NEW_MI
gcsnqzu9q0004    2023-2-13 22:14:00    14    10

那么铺垫做完了,这个需求的最终实现sql如下:

SQL> with t as
  2   (select sql_id,
  3           trunc(a.LAST_ACTIVE_TIME, 'mi') -
  4           mod(to_char(a.LAST_ACTIVE_TIME, 'mi'), 10) / 24 / 60 as new_tim
  5      from v$sql a)
  6      select * from (
  7  select new_tim, count(*) from t group by new_tim  order by new_tim desc nulls last
  8  )where rownum<=10;

NEW_TIM       COUNT(*)
----------- ----------
2023-2-15 19:00:00    476
2023-2-15 18:50:00    44
2023-2-15 18:40:00    20
2023-2-15 18:30:00    21
2023-2-15 18:20:00    52
2023-2-15 18:10:00    4
2023-2-15 18:00:00    7
2023-2-15 17:50:00    2
2023-2-15 17:40:00    7
2023-2-15 17:30:00    2


10 rows selected


SQL> 

总结

提示:这里对文章进行总结:

例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

相关文章
|
3月前
|
存储 数据管理 BI
揭秘数据仓库的奥秘:数据究竟如何层层蜕变,成为企业决策的智慧源泉?
【8月更文挑战第26天】数据仓库是企业管理数据的关键部分,其架构直接影响数据效能。通过分层管理海量数据,提高处理灵活性及数据一致性和安全性。主要包括:数据源层(原始数据)、ETL层(数据清洗与转换)、数据仓库层(核心存储与管理)及数据服务层(提供分析服务)。各层协同工作,支持高效数据管理。未来,随着技术和业务需求的变化,数仓架构将持续优化。
76 3
|
2月前
|
存储 机器学习/深度学习 数据管理
数据技术的进化史:从数据仓库到数据中台再到数据飞轮
数据技术的进化史:从数据仓库到数据中台再到数据飞轮
|
2月前
|
机器学习/深度学习 消息中间件 搜索推荐
【数据飞轮】驱动业务增长的高效引擎 —从数据仓库到数据中台的技术进化与实战
在数据驱动时代,企业逐渐从数据仓库过渡到数据中台,并进一步发展为数据飞轮。本文详细介绍了这一演进路径,涵盖数据仓库的基础存储与查询、数据中台的集成与实时决策,以及数据飞轮的自动化增长机制。通过代码示例展示如何在实际业务中运用数据技术,实现数据的最大价值,推动业务持续优化与增长。
79 4
|
2月前
|
SQL 安全 Go
SQL注入不可怕,XSS也不难防!Python Web安全进阶教程,让你安心做开发!
在Web开发中,安全至关重要,尤其要警惕SQL注入和XSS攻击。SQL注入通过在数据库查询中插入恶意代码来窃取或篡改数据,而XSS攻击则通过注入恶意脚本来窃取用户敏感信息。本文将带你深入了解这两种威胁,并提供Python实战技巧,包括使用参数化查询和ORM框架防御SQL注入,以及利用模板引擎自动转义和内容安全策略(CSP)防范XSS攻击。通过掌握这些方法,你将能够更加自信地应对Web安全挑战,确保应用程序的安全性。
85 3
|
1月前
|
存储 数据管理 大数据
从数据仓库到数据中台再到数据飞轮:社交媒体的数据技术进化史
从数据仓库到数据中台再到数据飞轮:社交媒体的数据技术进化史
|
3月前
|
SQL NoSQL 数据库
开发效率与灵活性:SQL vs NoSQL
【8月更文第24天】随着大数据和实时应用的兴起,数据库技术也在不断发展以适应新的需求。传统的SQL(结构化查询语言)数据库因其成熟的数据管理机制而被广泛使用,而NoSQL(Not Only SQL)数据库则以其灵活性和扩展性赢得了众多开发者的青睐。本文将从开发者的视角出发,探讨这两种数据库类型的优缺点,并通过具体的代码示例来说明它们在实际开发中的应用。
96 1
|
2月前
|
SQL 分布式计算 大数据
大数据开发SQL代码编码原则和规范
这段SQL编码原则强调代码的功能完整性、清晰度、执行效率及可读性,通过统一关键词大小写、缩进量以及禁止使用模糊操作如select *等手段提升代码质量。此外,SQL编码规范还详细规定了代码头部信息、字段与子句排列、运算符前后间隔、CASE语句编写、查询嵌套、表别名定义以及SQL注释的具体要求,确保代码的一致性和维护性。
84 0
|
3月前
|
Java Spring 监控
Spring Boot Actuator:守护你的应用心跳,让监控变得触手可及!
【8月更文挑战第31天】Spring Boot Actuator 是 Spring Boot 框架的核心模块之一,提供了生产就绪的特性,用于监控和管理 Spring Boot 应用程序。通过 Actuator,开发者可以轻松访问应用内部状态、执行健康检查、收集度量指标等。启用 Actuator 需在 `pom.xml` 中添加 `spring-boot-starter-actuator` 依赖,并通过配置文件调整端点暴露和安全性。Actuator 还支持与外部监控工具(如 Prometheus)集成,实现全面的应用性能监控。正确配置 Actuator 可显著提升应用的稳定性和安全性。
127 0
|
3月前
|
SQL 关系型数据库 MySQL
SQL Server、MySQL、PostgreSQL:主流数据库SQL语法异同比较——深入探讨数据类型、分页查询、表创建与数据插入、函数和索引等关键语法差异,为跨数据库开发提供实用指导
【8月更文挑战第31天】SQL Server、MySQL和PostgreSQL是当今最流行的关系型数据库管理系统,均使用SQL作为查询语言,但在语法和功能实现上存在差异。本文将比较它们在数据类型、分页查询、创建和插入数据以及函数和索引等方面的异同,帮助开发者更好地理解和使用这些数据库。尽管它们共用SQL语言,但每个系统都有独特的语法规则,了解这些差异有助于提升开发效率和项目成功率。
363 0
|
4月前
|
SQL JSON 数据库
influxdb 端点使用http进行sql查询,写数据
influxdb 端点使用http进行sql查询,写数据
269 0