求优化删除行的SQL:筛选特定Ticket与Subticket数据
优化筛选特定Ticket数据的SQL语句
问题背景
现有一张表包含Ticket、Subticket、Date、ProductID字段,规则如下:
- 每个
Ticket必然存在一行Subticket与自身值相等的记录 - 部分
Ticket还会包含Subticket与自身不等的其他记录 Ticket的记录是无序的
需要筛选两类数据:
- 所有
Subticket与Ticket值不相等的行 - 仅存在一行记录的
Ticket对应的那一行(也就是该Ticket只有Subticket等于自身的唯一记录)
目前已经用JOIN结合HAVING的方式实现,现在寻求更高效简洁的SQL写法。
优化方案1:使用窗口函数(推荐)
窗口函数可以在一次扫描中完成分组计数和条件判断,避免多表关联的开销,性能更优:
WITH ticket_counts AS ( SELECT *, COUNT(*) OVER (PARTITION BY Ticket) AS ticket_row_count FROM your_table_name ) SELECT Ticket, Subticket, Date, ProductID FROM ticket_counts WHERE Subticket != Ticket OR (ticket_row_count = 1 AND Subticket = Ticket);
逻辑说明
- 先用
COUNT(*) OVER (PARTITION BY Ticket)计算每个Ticket对应的总记录行数 - 筛选条件直接覆盖需求:
- 要么
Subticket不等于Ticket(对应第一类数据) - 要么该
Ticket只有一行记录且Subticket等于自身(对应第二类数据)
- 要么
优化方案2:使用EXISTS子查询
如果你的数据库对CTE支持有限,也可以用EXISTS子查询实现,同样比JOIN+HAVING更直观:
SELECT t1.Ticket, t1.Subticket, t1.Date, t1.ProductID FROM your_table_name t1 WHERE t1.Subticket != t1.Ticket OR NOT EXISTS ( SELECT 1 FROM your_table_name t2 WHERE t2.Ticket = t1.Ticket AND t2.Subticket != t1.Ticket );
逻辑说明
- 第一个条件直接筛选
Subticket不等于Ticket的行 - 第二个条件用
NOT EXISTS判断:当前Ticket不存在任何Subticket不等于自身的记录(也就是该Ticket只有一行Subticket等于自身的记录)
方案对比
- 窗口函数方案:只需要扫描表一次,性能最优,代码可读性高,适合大数据量场景
- EXISTS子查询方案:不需要CTE支持,逻辑清晰,适合不支持窗口函数的旧版本数据库
内容的提问来源于stack exchange,提问作者RRG
相关产品推荐
相关产品推荐

