以下のクエリは、range_startとrange_endの接頭辞と数値の評価を取得します。実施例の簡略化のため
Iは、以下のクエリはサブクエリとして上記のクエリを使用して、範囲のすべての値を生成する0-5
SELECT lstname,
regexp_substr(rangestart, '[^0-9]') AS Prefix,
regexp_substr(rangestart, '[0-9]') AS r_start,
regexp_substr(rangeend, '[0-9]') AS r_end
FROM table_1
LSTNAME |PREFIX |R_START |R_END |
--------|-------|--------|------|
Lst1 | |0 |5 |
Lst2 |a |0 |5 |
Lst3 |b |0 |5 |
の範囲を制限しました。
CROSS JOIN LATERAL
は、Oracle 12c以降のバージョンで動作します。以前のバージョンを使用している場合は、このクエリを書き直す必要があります。ただLEFT欠損値は、この表に上記のクエリをJOINとNULLでない値をフィルタリング見つけるには
SELECT * FROM table_2
RANGE |
------|
3 |
a0 |
a1 |
a5 |
b3 |
b4 |
b5 |
:
SELECT lstname, prefix || val AS val
FROM (
SELECT lstname,
regexp_substr(rangestart, '[^0-9]') AS Prefix,
regexp_substr(rangestart, '[0-9]') AS r_start,
regexp_substr(rangeend, '[0-9]') AS r_end
FROM table_1
) x
CROSS JOIN LATERAL (
SELECT LEVEL - 1 + x.r_start AS val
FROM dual
CONNECT BY LEVEL <= x.r_end - x.r_start + 1
)
LSTNAME |VAL |
--------|----|
Lst1 |0 |
Lst1 |1 |
Lst1 |2 |
Lst1 |3 |
Lst1 |4 |
Lst1 |5 |
Lst2 |a0 |
Lst2 |a1 |
Lst2 |a2 |
Lst2 |a3 |
Lst2 |a4 |
Lst2 |a5 |
Lst3 |b0 |
Lst3 |b1 |
Lst3 |b2 |
Lst3 |b3 |
Lst3 |b4 |
Lst3 |b5 |
そして今はtable_2
は、次の値が含まれていることを言います。
は、RANGE
は、Oracle
SELECT lstname, val
FROM (
SELECT lstname, prefix || val AS val
FROM (
SELECT lstname,
regexp_substr(rangestart, '[^0-9]') AS Prefix,
regexp_substr(rangestart, '[0-9]') AS r_start,
regexp_substr(rangeend, '[0-9]') AS r_end
FROM table_1
) x
CROSS JOIN LATERAL (
SELECT LEVEL - 1 + x.r_start AS val
FROM dual
CONNECT BY LEVEL <= x.r_end - x.r_start + 1
)
) XX
LEFT JOIN table_2 t2
ON t2."RANGE" = xx.val
WHERE t2."RANGE" IS NULL
ORDER BY 1, 2;
LSTNAME |VAL |
--------|----|
Lst1 |0 |
Lst1 |1 |
Lst1 |2 |
Lst1 |4 |
Lst1 |5 |
Lst2 |a2 |
Lst2 |a3 |
Lst2 |a4 |
Lst3 |b0 |
Lst3 |b1 |
Lst3 |b2 |
サブクエリのこのバージョンは、横方向が参加して、Oracleの10で動作するはずエミュレート
の予約語であるので、私は、この例では、列名として引用符で"RANGE"
を使用していますのでご注意くださいしかし、私はそれをテストしていません
SELECT lstname,
prefix || column_value AS val
FROM (
SELECT lstname,
regexp_substr(rangestart, '[^0-9]') AS Prefix,
regexp_substr(rangestart, '[0-9]') AS r_start,
regexp_substr(rangeend, '[0-9]') AS r_end
FROM table_1
) x
CROSS JOIN table(cast(multiset(
SELECT LEVEL - 1 + x.r_start AS val
FROM dual
CONNECT BY LEVEL <= x.r_end - x.r_start + 1
) as sys.OdciNumberList)) q
;
私は多くの場合、Javaでの作業よりもシリアル整数を含むテーブルに参加します。このデータをテーブルに入れる可能性はありますか? –
解決策とは別に、テーブルが小さければ、 'select distinct range from tab'クエリを実行し、DBから受け取ったデータからリストをクリーンアップします。 – Ambrish
これが一度しか行われない場合や、パフォーマンスやエレガンスが本当に心配されていない場合、 'lst'を通じたループのブルートフォースメソッドとDBのクエリが機能します。データベーステーブルが大きくなければ、1000のクエリが単純な回答になる可能性があります。 –