MySQL语法:大于值,但不是IN(...)

时间:2012-03-19 19:07:21

标签: mysql sql

表:

预订:id,user_id,object_id,date1,...

booking_status :id,book_id,status

状态为int,范围从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:对不起,在测试了不同的案例之后,我不得不承认我的说法太快了,说它有效......

4 个答案:

答案 0 :(得分: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所有已加入的行,但它不会过滤掉与{{1}的联接行具有相同bookings.id的联接行}}

答案 1 :(得分:1)

受到Ruakh解决方案的启发而没有相关的子查询:

select ...
from bookings b
join (select book_id from booking_status group by book_id having max(status) = 4
     ) bs on b.id = bs.book_id
left join user u on b.user_id = u.id

答案 2 :(得分:1)

这是一个没有子查询的方法:

SELECT b.date1, ..., u.name
FROM bookings b
LEFT JOIN user u ON u.id = b.user_id
JOIN booking_status bs1
  ON bs1.book_id = b.id AND bs1.status = 4
LEFT JOIN booking_status bs2
  ON bs2.book_id = b.id AND bs2.status > 4
WHERE b.object_id = $object_id
  AND b2.book_id IS NULL

此查询将删除任何存在同一ID大于4的状态的行。

答案 3 :(得分:1)

另一种方式

SELECT id, 
       user_id, 
       object_id, 
       date1 
FROM   bookings b 
       INNER JOIN (SELECT book_id 
                   FROM   booking_status 
                   GROUP  BY book_id 
                   HAVING MAX(CASE 
                                WHEN status >= 4 THEN status 
                              END) = 4) bs 
         ON bs.book_id = b.id 

(或响应评论时没有subselect的版本)

SELECT b.id, 
       b.user_id, 
       b.object_id, 
       b.date1 
FROM   bookings b 
       INNER JOIN booking_status bs 
         ON bs.book_id = b.id 
GROUP  BY b.id /* Other RDBMSs would require all columns listed*/
HAVING MAX(CASE 
             WHEN bs.status >= 4 THEN bs.status 
           END) = 4