SQL进阶之处理数列

本文深入探讨了在SQL中处理有序数列的方法,包括如何生成连续编号、查找质数、发现缺失编号,以及在处理有序数组时如何进行自连接,特别是涉及到连续票务分配的问题。通过实例展示了在不考虑换排和考虑换排的情况下,如何确保连续座位的可用性,并求解最长连续数量。此外,还讨论了单调递增和单调递减时间段的查询技巧。
摘要由CSDN通过智能技术生成

处理数列

越前须知(雾)

  • 本系列参考《SQL进阶教程》1,DBMS选用MySQL。
  • 本系列不涉及数据库安装与基础语句,对初学者存在一定门槛;基础知识建议阅读《SQL必知必会(第四版)》与《SQL基础教程(第二版)》。

概述

关系模型的数据结构中,没有“顺序”这一概念,因此SQL处理有序集合的方法,与过程语言(以处理顺序为目的)不同。

具体用法

连续编号

  • 创表
-- 连续编号 & 查询质数示例1
REATE TABLE Digits
 (digit INTEGER PRIMARY KEY);INSERT INTO Digits VALUES (0);
INSERT INTO Digits VALUES (1);
INSERT INTO Digits VALUES (2);
INSERT INTO Digits VALUES (3);
INSERT INTO Digits VALUES (4);
INSERT INTO Digits VALUES (5);
INSERT INTO Digits VALUES (6);
INSERT INTO Digits VALUES (7);
INSERT INTO Digits VALUES (8);
INSERT INTO Digits VALUES (9);

-- 查询缺失编号示例2
CREATE TABLE SeqTbl
 (seq INTEGER PRIMARY KEY);INSERT INTO SeqTbl VALUES (1);
INSERT INTO SeqTbl VALUES (2);
INSERT INTO SeqTbl VALUES (4);
INSERT INTO SeqTbl VALUES (5);
INSERT INTO SeqTbl VALUES (6);
INSERT INTO SeqTbl VALUES (7);
INSERT INTO SeqTbl VALUES (8);
INSERT INTO SeqTbl VALUES (11);
INSERT INTO SeqTbl VALUES (12);

Q:生成1-100、1-542的连续编号
A:把连续数表当成存储在各个数位上的“数字表”:先创建0-9的基础数表,再CROSS JOIN

-- 两位数
select D1.digit + (D2.digit * 10) as seq
    from Digits D1 cross join Digits D2
    order by seq;

-- 三位数,且限定编号
-- 因为原则上where的执行顺序比select早,所以不可以用 where seq between 1 and 542;
-- 但MySQL会先扫描select子句内容,MySQL可直接用seq
select D1.digit + (D2.digit * 10) + (D3.digit * 100) as seq
    from Digits D1 cross join Digits D2 cross join Digits D3
    where D1.digit + (D2.digit * 10) + (D3.digit * 100) between 1 and 542
    order by seq;

Q:寻找0-99中的质数
A:生成0-99编号的视图 + 质数条件

-- 生成 0-99 编号的视图
create view Numbers(seq) as
    select D1.digit + (D2.digit * 10)
    from Digits D1 cross join Digits D2;

-- NOT EXISTS + 否定 = 双重否定 <=> 肯定
select seq as prime
    from Numbers Dividend
    where seq > 1
    and not exists (select * from Numbers Divisor
                        where Divisor.seq <= Dividend.seq / 2  
                    -- 除了自身之外的约数必定小于等于自身值的一半(条件1)
                        and Divisor.seq <> 1   
                    -- 约数中不包含1(条件2)
                        and mod(Dividend.seq, Divisor.seq) = 0)
                    -- 在条件1&2的基础上,质数无法除尽,这里用“否定 + NOT EXISTS”表示肯定
    order by prime;

Q:查询表中缺失编号
A:用完整连续编号列表减现有表

-- 先创建连续编号视图
drop view Numbers;
create view Numbers(num) as 
  select D1.digit + (D2.digit * 10) + (D3.digit * 100)
    from Digits D1 cross join Digits D2 cross join Digits D3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值