HQL/JPA找到日期范围内的可用项目

问题描述:

这是汽车租赁应用程序。 我有表: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

我看到您的查询是正确的。

但是,如果你要根据车辆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' twistezo

+0

@twistezo是的,我错了什么,我编辑了我的答案,其实你的主要查询是正确的,但你错过了汽车id的条件 –

+0

好吧,我看到了,但我不想按特定的car_id搜索。我想从一个查询列出所有可用的汽车。 – twistezo

我认为你正在寻找一个完全重叠的时期。这是完全重叠正确的逻辑:

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' = startDate )'这对我没有任何回报。什么意思'选择1'在你的查询? – twistezo

+0

这似乎是正确的逻辑。'select 1'只是用来选择任何值,'1'很容易输入。看起来你整个这段时间都没有可用的汽车。 –