专栏首页SQL实现SQL 预定座位

SQL 预定座位

元旦假期就快到了,计划出去玩的朋友,都订好票了么?

今天,我们用 SQL 模拟订座的场景。

seats 是座位预定表,表结构如下:

CREATE TABLE `seats` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `row_no` int DEFAULT NULL COMMENT '第几排',
  `seat` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '座位',
  `status` int NOT NULL COMMENT '预定状态 0-未预定 1-已预定',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8

其中,id 是主键,从 1 起连续递增。

seats 表的数据:

    id  row_no  seat    status  
------  ------  ------  --------
     1       1  A              1
     2       1  B              1
     3       1  C              0
     4       1  D              0
     5       1  F              0
     6       2  A              1
     7       2  B              0
     8       2  C              0
     9       2  D              0
    10       2  F              0
    11       3  A              0
    12       3  B              1
    13       3  C              1
    14       3  D              0
    15       3  F              0

假设是 3 个朋友一起坐高铁出去玩,希望能预定到相邻的座位。现在这趟车某个车厢里每排的座位的编号是 A、B、C、D、F,其中,A 和 F 是靠窗位置,C 和 D 之间是过道。即使隔着过道,C 和 D 仍是可以看作是相邻的座位。

因此,预订到同一排的三个座位的编号是 A ~ C、B ~ D、C ~ F 其中一种都行。

如果你看了我的上一篇文章,你就会发现,这个需求和上一篇文章里面的需求很相似,只不过在这个需求里多了一个限定条件:要求连续的子序列在同一排(组)中。

我们把上一篇文章的实现方案稍微改改,就能实现本次的查询需求。

WITH cte AS 
(SELECT 
  *,
  row_number () over (PARTITION BY row_no 
ORDER BY id) AS rn 
FROM
  seats 
WHERE STATUS = 0) 
SELECT 
  a.row_no,
  CONCAT_WS('~', a.seat, b.seat) AS seat 
FROM
  cte a 
  INNER JOIN cte b 
    ON a.id + 2 = b.id 
    AND a.rn + 2 = b.rn 

预定到的座位>>>

row_no  seat    
------  --------
     1  C~F     
     2  B~D     
     2  C~F     

如果不用窗口函数呢,是否能实现?当然,也不是要换成用户变量(在 MySQL 中,可通过用户变量实现窗口函数的大部分功能)。我的意思是说,换个思路。

另一种实现方式的思路:获取同一排中所有相邻的三个座位,如果这三个座位都没有被预定,那就说明可以预定。

获取所有相邻的三个座位的 SQL 实现:

SELECT 
  a.row_no,
  CONCAT_WS('~', a.seat, b.seat) AS seat 
FROM
  seats a 
  INNER JOIN seats b 
    ON b.row_no = a.row_no AND b.id = a.id + 2 

相邻的三个座位 >>>

row_no  seat    
------  --------
     1  A~C     
     1  B~D     
     1  C~F     
     2  A~C     
     2  B~D     
     2  C~F     
     3  A~C     
     3  B~D     
     3  C~F     

再加上座位没有被预定的过滤条件,完整的 SQL :

SELECT 
  a.row_no,
  CONCAT_WS('~', a.seat, b.seat) AS seat 
FROM
  seats a 
  INNER JOIN seats b 
    ON b.row_no = a.row_no 
    AND b.id = a.id + 2 
WHERE a.status = 0 
  AND b.status = 0 
  AND NOT EXISTS 
  (SELECT 
    NULL 
  FROM
    seats c 
  WHERE c.id BETWEEN a.id 
    AND b.id 
    AND c.status = 1)

SQL 中在获取相邻的座位时把两头的座位已被预定的情况通过条件 WHERE a.status = 0 AND b.status = 0 提前排除了,当然,不加这个条件对结果也没什么问题。

本文分享自微信公众号 - SQL实现(gh_684ee9235a26),作者:zero

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-12-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • SQL练习笔记二:换座位

    题目:小美是一所中学的信息科技老师,她有一张 seat 座位表,平时用来储存学生名字和与他们相对应的座位 id。其中纵列的id是连续递增的小美想改变相邻俩学生的...

    用户6184845
  • SQL进阶-10-SQL处理序列

    在关系型数据库的数据结构中,默认是不考虑数据的顺序。处理有序集合在SQL中不能直接实现,但是可以通过集合和谓词来间接实现处理有序数据的需求。

    皮大大
  • LeetCode 1845. 座位预约管理系统(set)

    我的CSDN博客地址 https://michael.blog.csdn.net/

    Michael阿明
  • 「数据库」sql刷题(No.6)

    Hello 各位 ,我是公号「八点半技术站」的创作者 - Bruce.D (姓氏:豆)。

    八点半的Bruce、D
  • Jdbc操作数据库  改

    public static void main(String[] args) throws SQLException {

    明明如月学长
  • 数据科学家常见的5个SQL面试问题

    在任何以数据为中心的工作中,对SQL有深刻的理解都是成功的关键,尽管这不是工作中最有趣的部分。事实上,除了SELECT FROM WHERE GROUP BY ...

    博文视点Broadview
  • 【leetcode两题选手】MySQL类题目(八)

    某城市开了一家新的电影院,吸引了很多人过来看电影。该电影院特别注意用户体验,专门有个 LED显示板做电影推荐,上面公布着影评和相关电影描述。

    看、未来
  • MySQL简单实践(三)

    2),编写一个 SQL 查询,找出每个部门工资最高的员工。例如,根据上述给定的表格,Max在 IT 部门有最高工资,Henry 在 Sales 部门有最高工资:

    用户5473628
  • 你们要的代码来了

    张俊红
  • SQL vs NoSQL:如何选择?

    在前一篇文章中,我们讨论了 SQL 与 NoSQL 数据库之间基本的区别。接下来,我们我们将应用我们在特定场景中的知识来确定最佳的选择。

    哲洛不闹
  • 7天快速掌握MySQL-DAY5

    披头
  • SQL优化案例-从执行计划定位SQL问题(三)

    当SQL出现问题,能从执行计划中快速的定位哪部分出现问题很重要,SQL文本如下(为保证客户隐私,已经将注释和文字部分去掉):

    沃趣科技
  • SQL优化案例-从执行计划定位SQL问题(三)

    当SQL出现问题,能从执行计划中快速的定位哪部分出现问题很重要,SQL文本如下(为保证客户隐私,已经将注释和文字部分去掉):

    姚崇
  • 读累了看视频 :YouTube上最火的10个大数据视频

    翻译 | 伯乐在线 - 柒柒 原文来自Eileen McNulty 无论你对大数据一无所知,还是想要拓展机器学习方面的知识;无论你有三小时,还是三分钟;无论你...

    CDA数据分析师
  • 预测 lncRNA 亚细胞定位的网站

    在整个基因转录翻译的过程当中,基因是在细胞核发生转录,然后出核到细胞质当中发生翻译。对 lncRNA 而言,由于lncRNA的功能主要还是通过影响其它基因来实现...

    医学数据库百科
  • SQL vs NoSQL:如何选择?

    SQL 数据库: 在表中存储相关联的数据 在使用之前需要定义表的一个模式 鼓励标准化减少数据冗余 支持从多个表中检索相关数据表连接在一个单一的命令 实现数据完整...

    逸鹏
  • SQLServer 学习笔记之超详细基础SQL语句 Part 10

    -----------------------接Part 9-------------------

    授客
  • 首次揭秘!大麦如何应对超大规模高性能选座抢票?

    作者| 阿里文娱技术专家恒磊、高级开发工程师新钱 出品 | AI科技大本营(ID:rgznai100)

    AI科技大本营

扫码关注云+社区

领取腾讯云代金券