2016-04-29 85 views
0

我有兩個表(1令和2輛):查找可用日期

汽車

Cars

訂單

Orders

我試圖找到所有可用的汽車n日期。在這種情況下,我想在2016-05-03和2016-05-05之間找到所有可用的汽車。我檢查表示日期爲NOT BETWEEN的汽車或尚未在訂單中註冊的汽車(orders.car_id IS NULL)。下面是查詢:

SELECT destination, COUNT(destination) AS 'available cars' 
FROM cars 
LEFT JOIN orders ON cars.id = orders.car_id 

WHERE (orders.car_id IS NULL 

OR (

    date_to NOT BETWEEN '2016-05-03' AND '2016-05-05' 
    AND date_from NOT BETWEEN '2016-05-03' AND '2016-05-05' 

) 

) 

AND destination = 'Kristiansand' GROUP BY destination 

的問題是與奧迪A1使用id = 8。您可以看到,它已在兩次約會中註冊,一次是從2016-05-032016-05-05,另一次是從2016-04-292016-04-30

由於查詢中給定的日期是4月底的第二對日期是NOT BETWEEN,所以A1是遠離真實的可用車。

我正嘗試在克里斯蒂安桑的指定 日期之外取出所有可用於出租的汽車。

+0

你的問題是什麼?你究竟在努力實現什麼?我有點不清楚。 –

+0

@ConsiderMe我試圖在克里斯蒂安桑的指定日期之外取出所有可租賃的汽車。 – robert

+0

哪個表是'destination'字段? –

回答

1

比方說,你有2個時段T1和T2進行檢查,看他們是否重疊 你做這種檢查(T1.start < = T2.end)AND(T1.end> = T2 。開始)。

所以這種嘗試下面的查詢,(它檢查,並確保不存在重疊在規定的時間

SET @startdate = '2016-05-03',@enddate = '2016-05-05'; 

SELECT c.destination,COUNT(c.destination) as available_cars 
FROM cars c 
WHERE NOT EXISTS (SELECT 1 
        FROM orders o 
        WHERE o.car_id = c.id 
        AND o.date_from <= @enddate 
        AND o.date_to >= @startdate) 
AND c.destination = 'Kristiansand' 
GROUP BY c.destination 

http://sqlfiddle.com/#!9/9340e3/4

可以刪除SET同車的訂單聲明和硬編碼在你的@enddate和@startdate

+0

工作正常!它只返回了尚未隸屬於任何訂單的沃爾沃S80。 A1被排除在外。非常感謝! – robert

1

從排斥改變你的思維:

date_to NOT BETWEEN '2016-05-03' AND '2016-05-05' 
    AND date_from NOT BETWEEN '2016-05-03' AND '2016-05-05' 

以包容性的:

(date_from < '2016-05-03' AND date_to < '2016-05-05') OR 
    (date_from > '2016-05-03' AND date_to > '2016-05-05') 
+0

該查詢返回[this](https://i.gyazo.com/ba8f69a223c23f5b98695328168c9093.png)。儘管如此,這還是不對的。奧迪A1不應該出現,因爲它在2016-05-03和2016-05-05之間不可用。 **我將SELECT更改爲cars.id,brand,mode,date_from,date_to **。 – robert

1

,我認爲它會更容易發現哪些車是不可用,然後從列表中排除。事情是這樣的:

SELECT destination, COUNT(destination) AS 'available cars' 
FROM cars 
LEFT JOIN orders ON cars.id = orders.car_id 
     AND (date_to BETWEEN '2016-05-03' AND '2016-05-05' 
     OR date_from BETWEEN '2016-05-03' AND '2016-05-05') 

WHERE orders.car_id IS NULL 
    AND destination = 'Kristiansand' GROUP BY destination 
1

這是正確的,因爲加入你有理論上你有2個不同的AUDIs在結果集中我可以建議你se BETWEEN而不是NOT BETWEEN,獲取訂購的汽車,並使用以下子查詢語句NOT IN將其從汽車表中排除。

SELECT destination, COUNT(destination) AS 'available cars' 
FROM cars 
WHERE cars.id NOT IN (
    SELECT DISTINCT car_id FROM orders WHERE 
    date_to BETWEEN '2016-05-03' AND '2016-05-05' 
    AND date_from BETWEEN '2016-05-03' AND '2016-05-05' 
) 

注意:這個查詢沒有測試,我們可以做到這一點,如果你提供SQLFiddle或類似的東西。

P.S.有更多的最佳方法可以做到這一點,NOT EXISTS聲明或您可以使用子查詢JOIN