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; 
相关推荐
微学AI44 分钟前
时序大模型 TimechoAI 赋能工业时序数据底层技术优势与实操
数据库·大模型·时序大模型
北顾笙9801 小时前
MYSQL-day03
数据库·sql·mysql
MXsoft6181 小时前
**混合云统一监控实践:私有云+公有云的一体化运维方案**
运维·网络·数据库
瀚高PG实验室1 小时前
java中间件无法连接数据库
java·数据库·中间件·瀚高数据库
ULIi096kr1 小时前
MySQL大表优化终极方案:单表数据量上限、卡顿解决、分表分库实战教程
数据库·mysql
霖霖总总1 小时前
[MongoDB小技巧07]MongoDB 深度解析:find中投影与排序的底层机制与性能调优实战
数据库·mongodb
TechWayfarer1 小时前
云服务器地域怎么选:用离线IP数据库识别用户来源并优化部署
服务器·数据库·python·tcp/ip·数据分析
deviant-ART1 小时前
MySQL里的三个concat函数
数据库·mysql
H_老邪2 小时前
1044 - Access denied for user ‘root‘@‘%‘ to database ‘nacos‘
数据库·mysql
数智化精益手记局2 小时前
拆解复杂项目管理流程:用项目管理流程解决跨部门协作低效难题
大数据·运维·数据库·人工智能·产品运营