SQL典型练习题

with可以解决很多想用子表解决的问题

over可以加想加的,改变表的结构

例题:

表(driver)说明:司机登录登出明细表,由于同一司机有可能同时登录两个司机端,所以同一时间段一个司机有可能会产生两条或者更多条数据。

字段名 描述 类型:

driver_id 司机id bigint

login 登录时间 yyyy-mm-dd HH:MM:SS

exit 下线时间 yyyy-mm-dd HH:MM:SS

题目:请你统计2024年8月1日后的所有司机在线时长,要求对司机时间去重,每个司机在线时长精确到秒。

注:我们保证在8月1日0时做了一次司机清场,即保证不会有司机8月1日之前登录8月1日之后退出的情况出现。

法一:利用lead()加一列有效退出时间

法二:with语句

复制代码
WITH driver_time AS (
    SELECT driver_id, login AS event_time, 1 AS flag
    FROM driver
    WHERE login >= '2024-08-01'
    UNION ALL
    SELECT driver_id, exit AS event_time, -1 AS flag
    FROM driver
    WHERE exit >= '2024-08-01'
    -- 给出登录和登出的标志
),
driver_status AS (
    SELECT 
        driver_id,
        event_time,
        SUM(flag) OVER (PARTITION BY driver_id ORDER BY event_time) AS online_status
    FROM driver_time
    -- 给出在线状态
),
driver_intervals AS (
    SELECT 
        driver_id,
        event_time AS start_time,
        LEAD(event_time) OVER (PARTITION BY driver_id ORDER BY event_time) AS end_time,
        online_status
    FROM driver_status
    -- 用了lead()
)
SELECT 
    driver_id,
    SUM(TIMESTAMPDIFF(SECOND, start_time, end_time)) AS total_online_duration_seconds
FROM driver_intervals
WHERE online_status > 0
AND end_time IS NOT NULL
GROUP BY driver_id;

driver_id event_time flag online_status end_time

001 '2024-08-01 07:00:00' 1 1 '2024-08-01 08:00:00'

001 '2024-08-01 08:00:00' 1 2 '2024-08-01 09:00:00'

001 '2024-08-01 09:00:00' -1 1 '2024-08-01 10:00:00'

001 '2024-08-01 10:00:00' -1 0 '2024-08-01 11:00:00'

001 '2024-08-01 11:00:00' 1 1 '2024-08-01 12:00:00'

001 '2024-08-01 12:00:00' -1 0 null

相关推荐
IvorySQL2 小时前
PostgreSQL 分区表的 ALTER TABLE 语句执行机制解析
数据库·postgresql·开源
·云扬·3 小时前
MySQL 8.0 Redo Log 归档与禁用实战指南
android·数据库·mysql
野生技术架构师3 小时前
SQL语句性能优化分析及解决方案
android·sql·性能优化
IT邦德3 小时前
Oracle 26ai DataGuard 搭建(RAC到单机)
数据库·oracle
惊讶的猫3 小时前
redis分片集群
数据库·redis·缓存·分片集群·海量数据存储·高并发写
不爱缺氧i3 小时前
完全卸载MariaDB
数据库·mariadb
纤纡.3 小时前
Linux中SQL 从基础到进阶:五大分类详解与表结构操作(ALTER/DROP)全攻略
linux·数据库·sql
jiunian_cn4 小时前
【Redis】渐进式遍历
数据库·redis·缓存
橙露4 小时前
Spring Boot 核心原理:自动配置机制与自定义 Starter 开发
java·数据库·spring boot