SQL编程大师李鹏军:凭借高效的SQL策略,让算法设计与代码性能完美融合
数据库编程大赛:只用一条 SQL 秒杀 100 万张火车票
2024 第二届数据库编程大赛于 12 月 5 日正式开启初赛!由 NineData 和云数据库技术社区主办,华为云、Doris等协办单位和媒体共同举办。比赛要求选手设计一套SQL算法,只用一条 SQL 秒杀 100 万张火车票,让乘客都都能顺利坐上火车回家过年。查看赛题详情
以下是本次决赛第8名,SQL编程大师李鹏军的参赛介绍:
一、车次分配
思路和普通挑战的思路相同。
二、车厢分配。
总体思路:乘客编号减去车次的起始乘客编号,除以车厢座位数100,向上取整。
三、座位分配
1)排数。
总体思路:乘客编号最后两位,除以每排座位数5,向上取整。
细节:
特殊值,乘客编号为100的整数倍时,结果是0,而不是期待的20排。通过转换的小技巧处理一下。
2)列数(具体的座位( A,B,C,E,F ))。
总体思路:乘客编号减一,除以5得到的余数再+1。
细节:
select t.passenger_id,t.departure_station,t.arrival_station,t.train_id,case when t.ticket_status = 1 then CONCAT(t.coach_number,'') else null end coach_number,case when t.ticket_status = 1 then t.seat_number when t.ticket_status = 2 then '无座' else null end seat_numberfrom (select t.passenger_id,t.departure_station,t.arrival_station,t2.train_id,case when t.person_Rid between seat_count_all_step_lag + 1 and seat_count_all_step then 1 --有座when t.person_Rid between seat_count_all + seat_count_all_step_lag/10 + 1 and seat_count_all + seat_count_all_step/10 then 2 --无座else 3 --无票end ticket_status,CEILING((person_Rid-seat_count_all_step_lag)*1.0/100) coach_number --车厢号,CEILING(((person_Rid-1)%100+1)*1.0/5) row_num --第几排,(person_Rid-1)%5+1 col_num --第几列(具体的座位( A,B,C,E,F )),concat(CEILING(((person_Rid-1)%100+1)*1.0/5),case (person_Rid-1)%5+1 when 1 then 'A' when 2 then 'B' when 3 then 'C' when 4 then 'E' when 5 then 'F' end) seat_number --行列组合的最终座位号from (select passenger_id,departure_station,arrival_station,ROW_NUMBER() over(partition by departure_station,arrival_station order by passenger_id) person_Rid --相同起点终点的所有乘客进行编号from passenger) tleft join (select train_id,departure_station,arrival_station,seat_count,seat_count_all_step,coalesce(lag(seat_count_all_step) over(partition by departure_station,arrival_station order by train_id),0) seat_count_all_step_lag --相同起点终点的列车,上一车次允许乘坐乘客的结束编号,seat_count_allfrom (select train_id,departure_station,arrival_station,seat_count,sum(seat_count) over(partition by departure_station,arrival_station order by train_id) seat_count_all_step --相同起点终点的列车从第一车次到当前车次的总座位数,也是当前车次允许乘坐乘客的结束编号,sum(seat_count) over(partition by departure_station,arrival_station) seat_count_all --相同起点终点的所有列总的座位数总和from train) t) t2 on t.departure_station = t2.departure_station and t.arrival_station = t2.arrival_station and ( t.person_Rid between seat_count_all_step_lag + 1 and seat_count_all_step/*有坐票*/ or t.person_Rid between seat_count_all + seat_count_all_step_lag/10 + 1 and seat_count_all + seat_count_all_step/10/*百分之10的无座票*/ )) torder by t.passenger_id;
《数据库编程大赛》
下一次再聚!
感谢大家对本次《数据库编程大赛》的关注和支持,欢迎加入技术交流群,更多精彩活动不断,我们下次再相聚!