表格:
预订:id, user_id, object_id, date1, ...
booking_status: id, book_id, status
status 是整数,范围从 1 到 9(请求、确认、支付、用户取消等等),所以我需要所有预订,其中状态至少为 4(这意味着已支付)但没有更大的值超过 4(这意味着取消等)。
到目前为止,SELECT 看起来像这样(我省略了一些字段 (...) 以缩短它):
SELECT b.date1, ..., u.name FROM bookings b
LEFT JOIN user u ON (b.user_id = u.id)
LEFT JOIN booking_status bs ON (b.id=bs.book_id)
WHERE ((b.object_id=$object_id) AND (bs.status NOT IN (5,6,7,8,9)));"
...但它仍然会选择那些预订状态也大于 4 的预订。我需要如何更改查询有什么想法吗??
非常感谢您!
更新:再次感谢大家,我很惊讶你们想出了这么多好主意!真的有很多方法可以做到,我从你那里学到了很多,所以再次感谢你!我会尝试您的所有建议并查看性能,现在我将您的解决方案混合到此查询中,目前有效,但我需要进一步测试它:
SELECT b.date, ..., u.name FROM bookings b
LEFT JOIN user u ON (b.user_id = u.id)
LEFT JOIN booking_status bs ON (b.id=bs.book_id AND bs.status<=4)
WHERE (b.object_id=$object_id) HAVING MAX(bs.status)=4
不返回多行,只返回4行,排除大于4且没有子查询...
编辑 2:我再次编辑了查询...使用 HAVING MAX(bs.status)=4 它然后工作...
编辑 3:抱歉,在测试了不同的案例之后,我不得不承认我说它有效的速度太快了......
最佳答案
如果我没理解错的话,你需要的是:
SELECT b.date1, ..., u.name
FROM bookings b
LEFT JOIN user u ON b.user_id = u.id
WHERE b.object_id = ...
AND EXISTS
( SELECT 1
FROM booking_status bs
WHERE bs.book_id = b.id
AND bs.status = 4
)
AND NOT EXISTS
( SELECT 1
FROM booking_status bs
WHERE bs.book_id = b.id
AND bs.status > 4
)
;
您当前查询的问题是它过滤掉了所有 bs.status > 4
的连接行,但它没有过滤掉具有相同 bookings.id 的连接行
作为连接行,其中 bs.status > 4
。
关于MySQL 语法 : bigger than value, 但不在 (...),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9776329/