1

我需要帮助解决我一直在摸索但到目前为止我无法解决的问题。这不是关于jOOQ的特定问题,但我参考它来解释为什么我必须使用连接而不是特定于 ingres 的语法。那说:

想象一下下表和值:

create table  orderline
 (orderno integer,
 lineno integer,
 linetime timestamp,
 article varchar(30)
 );
insert into orderline values (1,1,timestamp '2013-10-23 00:05:08.0', 'SMURFS');
insert into orderline values (1,2,timestamp '2013-10-23 00:05:08.0', 'PINKMAN');
insert into orderline values (1,3,timestamp '2013-10-23 00:05:10.0', 'METH FAIRY');
insert into orderline values (1,4,timestamp '2013-10-23 00:05:12.0', 'HEISENBERG');
insert into orderline values (2,1,timestamp '2013-10-23 00:08:13.0', 'HEAR ME ROAR');
insert into orderline values (2,2,timestamp '2013-10-23 00:08:15.0', 'KHAALESI');
insert into orderline values (2,3,timestamp '2013-10-23 00:09:01.0', 'UNSULLIED');
insert into orderline values (2,4,timestamp '2013-10-23 00:09:03.0', 'WHITE WALKERS');
insert into orderline values (2,5,timestamp '2013-10-23 00:09:03.0', 'WILDLING');

现在我得到的只是在这个表上搜索的一个间隔。我必须给出的结果是来自特定订单的所有订单行,其中一行至少与时间间隔匹配。

例如,2013-10-23 00:05:08.0 和 2013-10-23 00:05:09.0 之间的时间间隔(含)应该在我的查询中给出 orderno=1 的 4 行,但只有 2 行匹配区间:orderno = 1、lineno = 1 的行和 orderno=1、lineno=2 的行。使用间隔的简单查询仅返回这 2 行。

在过去的 ingres 时代,我会这样搜索:

select * from orderline
where orderno in (
select orderno from orderline
  where linetime >= timestamp '2013-10-23 00:05:08.0'
  and linetime <= timestamp '2013-10-23 00:05:09.0'
)
order by orderno, lineno

这正好给出了我需要的 4 行。但是我不能使用这种语法,因为我必须使用 jOOQ 并且那里不存在这种语法(必须使用连接)。我不能让它与连接一起工作。

以下查询:

select * from orderline a
join orderline b
on a.orderno = b.orderno 
where b.linetime >= timestamp '2013-10-23 00:05:08.0'
and b.linetime <= '2013-10-23 00:05:09.0'

产生 8 行,即每行都重复。

如果我使用 2 个条件(orderno 和 lineno)作为连接条件,即

select * from orderline a
join orderline b
on a.orderno = b.orderno and a.lineno = b.lineno
where b.linetime >= timestamp '2013-10-23 00:05:08.0'
and b.linetime <= '2013-10-23 00:05:09.0'

我只得到 2 行,就像我对间隔进行了直接简单的查询一样。到目前为止,对右、左、内等连接的实验没有产生任何结果,所以我不知道如何去做(因此能够在 jOOQ 上编写它)。

任何人都知道我应该如何在 SQL92(即连接)语法上进行此查询?

4

2 回答 2

1

jOOQ支持所有标准 SQL 语句和子句。例如你的陈述:

select * from orderline
where orderno in (
select orderno from orderline
  where linetime >= timestamp '2013-10-23 00:05:08.0'
  and linetime <= timestamp '2013-10-23 00:05:09.0'
)
order by orderno, lineno

在 jOOQ(3.2 语​​法)中对应于此:

// Assuming this static import:
import static org.jooq.impl.DSL.*;

using(configuration)
.select().from(ORDERLINE)
.where(ORDERLINE.ORDERNO.in(
    select(ORDERLINE.ORDERNO)
    .from(ORDERLINE)
    .where(ORDERLINE.LINETIME.ge(Timestamp.valueOf("2013-10-23 00:05:08.0")))
    .and(ORDERLINE.LINETIME.le(Timestamp.valueOf("2013-10-23 00:05:09.0")))
))
.orderBy(ORDERLINE.ORDERNO, ORDERLINE.LINENO)
.fetch();

关于您的 JOIN 替代方案:

解决此问题的最佳方法是使用半连接,使用INorEXISTS谓词。您可以使用常规的 equi-join on orderno,但您必须加入一个只能获得不同orderno值的派生表:

select * 
from orderline a
join (
    select distinct orderno
    from orderline
    where linetime >= timestamp '2013-10-23 00:05:08.0'
    and linetime <= timestamp '2013-10-23 00:05:09.0'
) b
on a.orderno = b.orderno
order by orderno, lineno

我怀疑这个变体更快或更容易维护

于 2013-10-24T06:21:04.123 回答
0

你写了:

我只得到 2 行,就像我对间隔进行了直接简单的查询一样。

但是只有一次匹配区间。

我认为有一个错字,区别。并且可能这第二行导致了这个问题。

无论如何,如果您将第一个更改selectselect distinct.

于 2013-10-23T22:32:52.740 回答