
2024 第二届数据库编程大赛于 12 月 5 日正式开启初赛!由 NineData 和云数据库技术社区主办,华为云、Doris等协办单位和媒体共同举办。比赛要求选手设计一套SQL算法,只用一条 SQL 秒杀 100 万张火车票,让乘客都都能顺利坐上火车回家过年。查看赛题详情
以下是本次决赛第2名,SQL编程大师柳胜勋的参赛介绍:
参赛选手:柳胜勋
个人简介:PingCAP/TiDB研发工程师
参赛数据库:Doris
性能评测:百万级数据代码性能评测 1.201 秒
综合得分:88.25
以下是柳胜勋选手的代码说明思路简介:
1. 因为有10%的站票,而且必须买完所有坐票才能买站票,所以我们需要把座位票和无座票分开来卖。即把一列车变成成两列车卖,一列是有座的票,二列是10%的无座票。
2. 先处理有座的车,根据路径分组,车号排序。计算出每列车的起始编号。按照 200个座位一页拆分。比如800座的火车,拆分成4个页,也就是变成4条记录,以此类推。
3. 拆分后,使用窗口函数进行编号座位页号,根据路径分组,车号排序。因为每页的大小都是一样的。所以 路径+页号 是唯一的。
4. 同时,我们使用函数窗口,计算出同一条线路上的乘客编号。
5. 因为有页号,所以可以乘客编号可以对 200 取模,使用JOIN快速映射到记录。
6. 通过这次JOIN后,有座的票就分好了。同时可以根据编号减去列车的起始编号,获得列车上的座位序号,然后除法和取余计算出座位号。
7. 将上一步的结果筛选出未分配列车的乘客,和上面一样的方式,只是按照20一页来取模计算页号。因为无座,所以不需要算车厢号,座位号直接标记无座即可。
8. 将结果和之前有座乘客UNION ALL 一下,然后做最终排序就是结果。
以下是柳胜勋选手的详细算法说明,结尾附完整SQL:
1.首先生成列车的车票信息。借用自增数列t_sequence,通过与train连接,生成车厢号、座位号。另外,生成10%的无座车票。为便于对车票排序,额外生成是否有座说明列