SQL 处理数列

在关系模型的数据结构中,并没有"顺序"这一概念。因此,基于它实现的关系数据库中的表和视图的行和列也必然没有顺序。

1 处理数列

1.1 实践

1.1.1 生成连续编号

图 t_num 数据库源与目标视图v_seq

需求:根据0~9 这10个数,生成0~999的连续按升序排列的数列,并创建视图v-seq。

sql 复制代码
create view v_seq(seq) as 
select n1.num + n2.num * 10 + n3.num * 100 as seq
from t_num n1
cross join t_num n2 
cross join t_num n3 
order by seq 

1.1.2 求全部的缺失编号

表 连续编号t_seq_num 表 及期望输出

需求:找出t_seq_num 表中缺失的编号。

sql 复制代码
-- except
select seq 
from v_seq 
where seq between (select min(seq) from t_seq_num) and (select max(seq) from t_seq_num)
except 
select seq 
from t_seq_num;

-- NOT EXISTS 
select seq 
from v_seq v
where seq between (select min(seq) from t_seq_num) and (select max(seq) from t_seq_num)
and not exists 
(
select *
from t_seq_num s 
where s.seq = v.seq 
);

-- 连接
select t1.seq 
from (
select seq 
from v_seq v
where seq between (select min(seq) from t_seq_num) and (select max(seq) from t_seq_num)
) t1 
left join t_seq_num t2 on t1.seq = t2.seq 
where t2.seq is null; 

1.1.3 3个人能坐得下吗

图 座位预定t_seats 表及期望输出

需求:找出座位号连续3个为"未预定的组合"。

sql 复制代码
-- not exists
select s1.seat as begin_seat, s2.seat as end_seat 
from t_seats s1
cross join t_seats s2 
where s2.seat = s1.seat + 2 
and not exists (
select *
from t_seats s3 
where s3.seat between s1.seat and s2.seat 
and s3.status != '未预定'
);

-- 窗口函数
select *
from (
select seat as begin_seat,
max(seat) over(order by seat rows between 2 following and 2 following) as end_seat
from t_seats 
where `status` = '未预定'
) tmp 
where end_seat - begin_seat = 2;

-- group by 
select s1.seat as begin_seat,s2.seat as end_seat 
from t_seats s1 
cross join t_seats s2 
cross join t_seats s3 
where s2.seat = s1.seat + 2 and s3.seat between s1.seat and s2.seat 
group by s1.seat,s2.seat
having count(*) = sum(case when s3.status = '未预定' then 1 else 0 end);

1.1.4 有换排的座位, 3个人能坐下吗?

图 有换排的座位预定情况t_seats2表及期望输出

需求:找出同排,且连续3个座位号都为未预定的组合。

sql 复制代码
-- not exists
select s1.seat as begin_seat,s2.seat as end_seat
from t_seats2 s1 
cross join t_seats2 s2 
where s2.seat = s1.seat + 2 
and not exists (
select * 
from t_seats2 s3 
where s3.seat between s1.seat and s2.seat 
and ( s3.line_id != s1.line_id or s3.status != '未预定' )
);

-- 窗口函数 
select *
from (
select seat as begin_seat, 
max(seat) over (partition by line_id order by seat rows between 2 following and 2 following) as end_seat
from t_seats2
where status = '未预定'
) temp
where end_seat - begin_seat = 2; 

-- group by 
select s1.seat as begin_seat,s2.seat as end_seat 
from t_seats2 s1
cross join t_seats2 s2
cross join t_seats2 s3
where s2.seat = s1.seat + 2 and s3.seat between s1.seat and s2.seat 
group by s1.seat,s2.seat 
having count(*) = SUM(case when s3.line_id = s1.line_id and s3.status = '未预定' then 1 else 0 end);

1.1.5 单调递增区间

图 股票每日价格t_stocks表及期望输出

需求:找出单调递增区间。

sql 复制代码
-- 查找出与前日相比,股价上市的交易日
create view v_up_stocks as 
select *
from 
(
select 
deal_date,price,
case sign(price - max(price) over(order by deal_date rows between 1 preceding and 1 preceding)) 
when 1 then 'up'
when 0 then 'eq'
when -1 then 'down'
else '~'
end as sign,
row_number() over (order by deal_date) as row_num
from t_stocks
) tmp
where sign = 'up'

图 上市的股票交易日信息视图v_up_stocks

sql 复制代码
select min(deal_date) as begin_date,max(deal_date) as end_date
from (
select s1.deal_date,min(s1.row_num) - count(s1.deal_date) as gap 
from v_up_stocks s1 
cross join v_up_stocks s2 
where s1.deal_date >= s2.deal_date 
group by s1.deal_date
) tmp
group by gap 
order by begin_date; 
相关推荐
ClickHouseDB2 小时前
ClickHouse Cloud 与 Snowflake 实时性价比对比:CostBench 测试中的 412 倍差距来
运维·数据库·系统架构
m0_639906942 小时前
Redis入门|五种数据结构、使用场景、持久化RDB&AOF
数据结构·数据库·redis
时间售卖铺3 小时前
触发器与函数实战:MySQL高效编程秘诀
运维·数据库·mysql·云原生
qetfw3 小时前
UOS MariaDB 数据库:安装、最小权限与备份验证
linux·数据库·mariadb·uos
数智园区合作社4 小时前
问数平台怎么把同一个指标锁成一个数
大数据·数据库·人工智能·ai
lbb 小魔仙4 小时前
Windows搭建PaddleOCR+飞书Webhook自动打卡通知机器人:识别、推送与远程触发完整教程
数据库·人工智能·prometheus·时序数据库
captain3765 小时前
MyBatis操作数据库(入门2)
java·数据库·spring boot·后端·spring·mybatis
心中有你02146 小时前
Java实现Dijkstra最短路径算法(邻接表 + 优先队列)
java·数据库·算法
龙亘川6 小时前
综合素质评价业务建模:从过程性评价到成长档案全链路闭环
数据库·智慧城市·数据可视化
数据库小组6 小时前
NineData 实战教程:MySQL 5.5 数据迁移同步到 MySQL 8.0(跨版本升级)
数据库·mysql·mysql优化·数据库开发·数据库迁移·版本升级·数据复制