You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何查询已全额支付的门票?SQL嵌套查询实现方案问询

查询所有已全额支付门票的SQL实现

针对你的需求,我提供两种实用的SQL写法,适配大部分主流关系型数据库(MySQL、PostgreSQL、SQL Server等),逻辑清晰且性能友好:

方法一:关联子查询(直观易懂)

这种写法直接在WHERE子句中对每个门票对应的booking进行总额校验,逻辑和你描述的伪SQL高度贴合:

SELECT t.*
FROM tickets t
WHERE (
    -- 计算当前booking的总支付金额,无支付记录时返回0
    SELECT COALESCE(SUM(p.amount), 0)
    FROM payments p
    WHERE p.booking_id = t.booking_id
) >= (
    -- 计算当前booking的总门票价格
    SELECT SUM(t2.price)
    FROM tickets t2
    WHERE t2.booking_id = t.booking_id
);

关键细节:

  • COALESCE(SUM(p.amount), 0):处理没有支付记录的booking(此时SUM返回NULL,直接对比会不成立,转为0后能正确识别未支付的情况)。
  • 每个ticket都会触发两次子查询,分别校验对应booking的支付总额是否≥门票总价,符合条件的门票才会被返回。

方法二:预聚合关联(性能更优)

如果数据量较大,重复子查询会影响效率,我们可以先通过CTE预计算所有符合条件的booking,再关联门票表:

WITH valid_bookings AS (
    SELECT
        t.booking_id,
        SUM(t.price) AS total_ticket_cost,
        COALESCE(SUM(p.amount), 0) AS total_paid
    FROM tickets t
    LEFT JOIN payments p ON t.booking_id = p.booking_id
    GROUP BY t.booking_id
    -- 提前筛选出已全额支付的booking
    HAVING COALESCE(SUM(p.amount), 0) >= SUM(t.price)
)
SELECT t.*
FROM tickets t
JOIN valid_bookings vb ON t.booking_id = vb.booking_id;

关键细节:

  • 先通过valid_bookings CTE一次性计算所有booking的总额并筛选出符合条件的,避免重复计算。
  • LEFT JOIN确保没有支付记录的booking也会被纳入计算(最终会被HAVING过滤)。
  • 最后通过JOIN直接获取这些有效booking下的所有门票记录,性能比子查询更稳定。

额外提示

  • 建议给tickets.booking_id和payments.booking_id添加索引,能大幅提升聚合查询的速度。
  • 如果你的数据库支持窗口函数,还可以用窗口函数简化写法,但上面两种方法兼容性更广,适合多数场景。

内容的提问来源于stack exchange,提问作者Sebastian Walker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:39:03