我必须从Oracle DB中提取一些特定的数据。我使用的是Java 8。我必须考虑表中的3列:标志\ date_1 \ date_2。标志可以有值1、2或3(标志值在一段时间内或根据某些事件从1->2->3更新)。
对于两个dateTime值X和Y,我需要从日期值在X和Y之间的表中提取所有行。如果标志值为1或2,则date_1必须介于X&Y之间,而不论date_2。但是如果标志值为3,则date_2必须介于X&Y之间,而不考虑date_1。
为此,我使用不同的参数创建了三个不同的查询,分别为标志=1/标志=2/标志=3,但这似乎是非常低效率的。
String sql1 = "SELECT new xxxx.xxxx.xxx.Java.class.xxx ("
+ "t.flag, t.date_1, t.date_2)"
+ "FROM Table t "
+ "WHERE t.flag = :flagValue1 "
+ "AND t.date_1 >= :X "
+ "AND t.date_1 < :Y ";
String sql2 = "SELECT new xxxx.xxxx.xxx.Java.class.xxx ("
+ "t.flag, t.date_1, t.date_2)"
+ "FROM Table t "
+ "WHERE t.flag = :flagValue2 "
+ "AND t.date_1 >= :X "
+ "AND t.date_1 < :Y ";
String sql3 = "SELECT new xxxx.xxxx.xxx.Java.class.xxx ("
+ "t.flag, t.date_1, t.date_2)"
+ "FROM Table t "
+ "WHERE t.flag = :flagValue3 "
+ "AND t.date_2 >= :X "
+ "AND t.date_2 < :Y ";
List<E> list1 = this.entityManger.createQuery(sql1, model.class)
.setParameter("1", flag1)
.setParameter("X", firstDateValue)
.setParameter("Y", secondDateValue)
.getResultList();
List<E> list2 = this.entityManger.createQuery(sql2, model.class)
.setParameter("2", flag2)
.setParameter("X", firstDateValue)
.setParameter("Y", secondDateValue)
.getResultList();
List<E> list3 = this.entityManger.createQuery(sql3, model.class)
.setParameter("3", flag3)
.setParameter("X", firstDateValue)
.setParameter("Y", secondDateValue)
.getResultList();
List<E> finalList = new ArrayList<>();
finalList.addAll(list1);
finalList.addAll(list2);
finalList.addAll(list3);
return finalList;还有别的办法吗?对此有什么更好的(单一)查询?
PS:我想知道我是否可以使用Java 8的Lambda函数来过滤列表中的值。对此有什么建议吗?
谢谢你的帮助。
发布于 2017-03-06 11:13:41
如果我正确理解它,您实际上有两个输入参数X&Y(也就是从/到现在)。并且您总是希望查询所有标志的值,这些标志涉及输入的日期。因此,这样的查询会更有效:
select new Java.class.name (t.flag, t.date_1, t.date_2) from Table t
where
(t.flag in (1,2) and t.date_1 >= :X and t.date_1 < :Y)
or
(t.flag = 3 and t.date_1 2= :X and t.date_2 < :Y)这会把整件事简化成一个查询..。可能仍然没有效率,这取决于数据集。
https://stackoverflow.com/questions/42623687
复制相似问题