如果条件不正确,则左外连接

时间:2015-11-19 15:22:37

标签: sql ruby-on-rails postgresql

我在SQL查询中苦苦挣扎。最近在Rails上花了太多时间!

我有三张桌子

Panels
id

BookingPanel (join table)
panel_id
booking_id

Booking
id
from_date
to_date

我想选择在特定日期没有预订的所有面板。我尝试了以下方法:

SELECT COUNT(*) FROM "panels" 
LEFT JOIN "booking_panels" ON "booking_panels"."panel_id" = "panels"."id" 
LEFT JOIN "bookings" ON "bookings"."id" = "booking_panels"."booking_id" 
WHERE (bookings.from_date != '2015-04-11' AND bookings.to_date != '2015-04-16')

由于某种原因,它不会返回任何东西。如果我将dates where子句更改为=而不是!=那么它会正确查找在该日期预订的记录。为什么不这样做?=找到相反的结果?

2 个答案:

答案 0 :(得分:1)

应用WHERE条件,由于NULL != <anything>永远不会计算为true这一事实,您可以将好的左连接压缩到等效的内连接中。这种变化应该可以解决问题:

SELECT COUNT(*)
FROM "panels" 
  LEFT JOIN "booking_panels"
    ON "booking_panels"."panel_id" = "panels"."id" 
  LEFT JOIN "bookings"
    ON "bookings"."id" = "booking_panels"."booking_id" 
    AND (bookings.from_date = '2015-04-11' OR bookings.to_date = '2015-04-16')
WHERE "bookings"."id" IS NULL

答案 1 :(得分:0)

为此,我会考虑not exists

select count(*)
from panels p
where not exists (select 1
                  from booking_panes bp join
                       bookings b
                       on b.id = bp.booking_id
                  where bp.panel_id = p.id and
                        <date> >= b.from_date and
                        <date> < b.to_date + interval '1 day'
                 );

注意:您的问题具体是关于一个日期。但是,示例查询有两个日期,这相当令人困惑。