2017-03-03 55 views
1

這是汽車租賃應用程序。 我有表:HQL/JPA找到日期範圍內的可用項目

+-------------------------------------+ 
|id |start_date |end_date |car_id| 
+----+------------+------------+------+ 
|1 |2017-04-01 |2017-04-10 |1  | 
|2 |2017-04-15 |2017-04-20 |1  | 
|3 |2017-04-15 |2017-04-20 |2  | 
+----+------------+------------+------+ 

用於查找用戶輸入「userDateStart」和「userDateEnd」之間的所有可用汽車的Hibernate查詢。

select 
b.id, b.startDate, b.endDate, b.car.id 
from BorrowedDate as b 
where :userDateStart not between startDate and endDate 
and :userDateEnd not between startDate and endDate 

------------ 
:userDateStart = 2017-04-02 00:00:00 
:userDateEnd = 2017-04-10 00:00:00 

我的結果是:因爲車ID = 1這個時間是借來的

+-------------------------------------+ 
|id |start_date |end_date |car_id| 
+----+------------+------------+------+ 
|2 |2017-04-15 |2017-04-20 |1  | 
|3 |2017-04-15 |2017-04-20 |2  | 
+----+------------+------------+------+ 

結果是錯誤的。只有car_id = 2應該可用。

+1

看起來正確的我。它在id = 2的行上可用 –

+0

它不正確@JackFlamp,因爲在此時間範圍內car_id = 1不可用。它在其他日期可用。但我想要在userinput的特定時間範圍內有可用的汽車列表。 – twistezo

回答

2

我看到您的查詢是正確的。

但是,如果你要根據車輛ID來選擇,所以你應該添加車ID作爲條件太到你的查詢

例如

SELECT b.id, b.startDate, b.endDate, b.car.id 
FROM BorrowedDate b 
WHERE :userDateStart NOT BETWEEN b.startDate AND b.endDate 
AND :userDateEnd NOT BETWEEN b.startDate AND b.endDate 
AND b.car.id = :carId 

或者你可以那樣做太

SELECT b.id, b.startDate, b.endDate, c.id 
FROM BorrowedDate b INNER JOIN b.car c 
WHERE :userDateStart NOT BETWEEN b.startDate AND b.endDate 
AND :userDateEnd NOT BETWEEN b.startDate AND b.endDate 
AND c.id = :carId 

,那麼你必須通過:carId值等於2

UPDATE

,如果你需要得到結果的動態,你可以試試這個SQL查詢,我會很快與JPQL更新

SELECT b.id, b.startDate, b.endDate, b.car.id 
FROM BorrowedDate b 
WHERE '2017-04-02 00:00:00' NOT BETWEEN b.startDate AND b.endDate 
AND '2017-04-10 00:00:00' NOT BETWEEN b.startDate AND b.endDate 
AND b.car.id NOT IN (SELECT DISTINCT bd.car.id FROM BorrowedDate bd WHERE '2017-04-02 00:00:00' BETWEEN bd.startDate AND bd.endDate OR '2017-04-10 00:00:00' BETWEEN bd.startDate AND bd.endDate) 

這裏有JPQL

SELECT model.id, model.startDate, model.endDate, model.car.id 
FROM BorrowedDate model 
WHERE :userDateStart NOT BETWEEN model.startDate AND model.endDate 
AND :userDateEnd NOT BETWEEN model.startDate AND model.endDate 
AND model.car.id NOT IN (SELECT DISTINCT b.car.id FROM BorrowedDate b WHERE :userDateStart BETWEEN b.startDate AND b.endDate OR :userDateEnd BETWEEN b.startDate AND b.endDate) 
+0

您的查詢@ mibrahim.iti無法正常工作。 'SELECT b.id,b.startDate,b.endDate,b.car.id FROM BorrowedDate b WHERE'2017-04-02 00:00:00'> = b.startDate AND'2017-04-10 00:00:00'<= b.endDate',結果是'| 1 | 2017-04-01 | 2017-04-10 | 1 |'我們有id,start_date,end_date,car_id。我想在可用的汽車的結果列表中。對於這個日期範圍,我應該只提供id = 2的車。 – twistezo

+0

@twistezo是的,我錯了什麼,我編輯了我的答案,其實你的主要查詢是正確的,但你錯過了汽車id的條件 –

+0

好吧,我看到了,但我不想按特定的car_id搜索。我想從一個查詢列出所有可用的汽車。 – twistezo

0

我認爲你正在尋找一個完全重疊的時期。這是完全重疊正確的邏輯:

select b.id, b.startDate, b.endDate, b.car.id 
from BorrowedDate as b 
where :userDateStart <= startDate and 
     :userDateEnd >= endDate; 

所以,這可以讓你所租用的客戶希望一個整個週期的汽車。這可能不是你的意圖。

讓我假設你想要的汽車在此期間可用。對於這一點,讓我假設你有一個cars表:

select c.* 
from cars as c 
where not exists (select 1 
        from borrowed b 
        where :userDateStart <= endDate and 
         :userDateEnd >= startDate 
       ); 

注:這是標準的(ISH)SQL。 Hibernate有一些不尋常的約定,但這個想法應該是一樣的。

+0

應該看起來像這樣嗎? 'select b.car.id from Car as c,BorrowedDate as b Where does not exist (select 1 from b where'2017-04-02 00:00:00'<= endDate and'2017-04- 10 00:00:00'> = startDate )'這對我沒有任何回報。什麼意思'選擇1'在你的查詢? – twistezo

+0

這似乎是正確的邏輯。'select 1'只是用來選擇任何值,'1'很容易輸入。看起來你整個這段時間都沒有可用的汽車。 –