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');

今与えられているのは、このテーブルを検索する間隔だけです。私が与えなければならない結果は、特定の注文からのすべての注文明細であり、少なくとも 1 つの明細は時間間隔と一致します。

たとえば、2013-10-23 00:05:08.0 と 2013-10-23 00:05:09.0 の間の間隔は、クエリの結果としてorderno=1 の 4 行を与えるはずですが、2 行しかありません。 interval を一致させます: 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述語を使用して、セミ結合を使用することです。で通常の​​等結合を使用できますが、個別の値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 に答える