我在DB中有包含date_start
和date_finish
列的表。这是日期范围和date_start <= date_finish
。我的代码中还有Range(dateStart, dateFinish)
和dateStart <= dateFinish
类的日期范围。然后,我想在DB表中找到日期范围与代码中的范围有交集(包括边框)的记录。
我为这个条件编写了生成BooleanExpression的下一个函数:
public static BooleanExpression dateRangeIntersection(Range<Date> range, TemporalExpression<Date> pathStart, TemporalExpression<Date> pathFinish) {
return pathStart.gt(range.getLast()).
or(pathFinish.lt(range.getFirst())).
not();
}
我希望得到下一个sql条件(示例日期范围从2016-01-01到2016-01-04 ):
SELECT * FROM table t WHERE NOT (t.date_start > '2016-01-04' OR t.date_finish < '2016-01-01')
结果是:
SELECT * FROM table t WHERE t.date_start <= '2016-01-04' AND t.date_finish >= '2016-01-01'
这一条件是错误的,因为它只能适用于一种情况,当表中的范围完全包括在范围为2016-01-01、2016-01-04时。
我认为QueryDsl试图更简单地理解这个条件并重写它。但在这种情况下,它就错了。
有人知道如何在querydsl中禁用条件优化或重写条件以获得预期的sql吗?
发布于 2015-12-19 02:35:20
当将NOT
合并到子表达式中时,可以将所有比较(例如,=
变为<>
,>
变为<=
)和交换AND
与OR
,因此这两个表达式是相同的:
NOT (a > b OR c < d)
a <= b AND c >= d
这正是你所拥有的。它做得对。
你的情况变成:t.date_start <= '2016-01-04' AND t.date_finish >= '2016-01-01'
当您说只有表中完全包含在range中的范围[2016-01-01, 2016-01-04]
才能工作时,您就错了。
试试[2015-10-25, 2016-01-02]
t.date_start <= '2016-01-04' AND t.date_finish >= '2016-01-01'
`2015-10-25` <= '2016-01-04' AND `2016-01-02` >= '2016-01-01'
TRUE AND TRUE
是的,这和预期的一样:[2015-10-25, 2016-01-02]
与[2016-01-01, 2016-01-04]
相交。
https://stackoverflow.com/questions/34369614
复制