SQL面试题练习 —— 计算用户首单是即时单的比例

目录

  • [1 题目](#1 题目)
  • [2 建表语句](#2 建表语句)
  • [3 题解](#3 题解)

题目来源:美团。

1 题目

在外卖订单中,有时用户会指定订单的配送时间。现定义:如果用户下单日期与期望配送日期相同则认为是即时单,如果用户下单日期与期望配送时间不同则是预约单。每个用户下单时间最早的一单为用户首单,请计算用户首单中即时单的占比。

t_user_order

2 建表语句

sql 复制代码
--建表语句
CREATE TABLE t_user_order
(
order_id string COMMENT '订单ID',
user_id string COMMENT '用户ID',
order_time string comment '下单时间',
desire_date string comment '期望送达日期'
) COMMENT '用户订单记录表'
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' 
;
--插入数据
insert into t_user_order
values
('1001','001','2024-07-01 12:01:23','2024-07-01'),
('1002','001','2024-07-01 12:03:23','2024-07-02'),
('1003','002','2024-07-01 13:03:23','2024-07-02'),
('1004','002','2024-07-01 13:07:23','2024-07-01'),
('1005','003','2024-07-01 15:03:23','2024-07-01')

3 题解

  1. 找到用户首单,并判断是否是即时单
sql 复制代码
select order_id,
       user_id,
       order_time,
       desire_date,
       is_instant
from (select order_id,
             user_id,
             order_time,
             desire_date,
             if(to_date(order_time) = to_date(desire_date), 1, 0)              as is_instant,
             row_number() over (partition by user_id order by order_time asc ) as rn
      from t_user_order) t
where rn = 1

执行结果

  1. 统计用户首单总单数和即时单数
sql 复制代码
select 
    count(case when is_instant = 1 then order_id end) as instant_cnt,
    -- count(if(is_instant = 1, order_id, null)) as instant_cnt,
    count(order_id) as total_cnt
from (select order_id,
             user_id,
             order_time,
             desire_date,
             if(to_date(order_time) = to_date(desire_date), 1, 0)              as is_instant,
             row_number() over (partition by user_id order by order_time asc ) as rn
      from t_user_order) t
where rn = 1

执行结果

  1. 计算即时单比例
sql 复制代码
select
    round(count(case when is_instant = 1 then order_id end)/count(order_id),2) as instant_per
from (select order_id,
             user_id,
             order_time,
             desire_date,
             if(to_date(order_time) = to_date(desire_date), 1, 0)              as is_instant,
             row_number() over (partition by user_id order by order_time asc ) as rn
      from t_user_order) t
where rn = 1

执行结果

相关推荐
Leon-Ning Liu几秒前
Oracle GoldenGate Replicat Abend:Key Column Missing 根因分析与修复
数据库·oracle
IvorySQL10 小时前
PostgreSQL 日报 | JOIN 与外键优化(8 月 9 日)
数据库·postgresql
ltl10 小时前
自治数据库十年回顾:Peloton、NoisePage、OtterTune 到云原生 auto-tuning
数据库
灯澜忆梦11 小时前
【MySQL10】进阶篇 | 索引_#2性能优化
数据库·sql·mysql·性能优化
C++ 老炮儿的技术栈13 小时前
从 Qt Designer 属性编辑器的层级可以看到继承链
c语言·数据库·c++·qt·sqlite·visual studio
MC皮蛋侠客13 小时前
Redis 系列(一):全景与最小闭环——从 `SET` 命令到内存数据结构
数据结构·数据库·redis
zt1985q15 小时前
本地部署开源网络书签与内容管理工具 Karakeep 并实现外部访问
运维·服务器·网络·数据库·网络协议·开源
IvorySQL16 小时前
PostgreSQL 日报| PostgreSQL 19 默认 WAL 压缩算法(8 月 8 日)
数据库·postgresql·区块链
油丶酸萝卜别吃16 小时前
MySQL B+ 树查询全过程详解
数据库·mysql
leisoo809716 小时前
股票数据本地化存储实战:JSON、数据库与列式存储的方案对比
jvm·数据库·json