HQL / JPA在日期范围之间查找可用项

时间:2017-03-03 15:01:23

标签: java mysql sql hibernate jpa

这是汽车租赁应用程序。 我有桌子:

var result = MyCollection.Where(p => 
                       p.Staff_Name_First != null && 
                       p.Staff_Name_First.StartsWith(myString) &&
                       p.Is_Alive); 

Hibernate查询用于查找用户输入'userDateStart'和'userDateEnd'之间的所有可用汽车。

+-------------------------------------+
|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     |
+----+------------+------------+------+ 

我的结果是:

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的汽车。只有car_id = 2可用。

2 个答案:

答案 0 :(得分: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

<强>更新

如果你需要动态获得结果,你可以尝试这个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)

答案 1 :(得分: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有一些不寻常的约定,但这个想法应该是一样的。