PostgreSQLでWITH RECURSIVE
クエリを使用することは可能ですか?ここで、再帰的な用語は異なるテーブルの結合です。私のユースケースは、テーブルといくつかの論理ルールからいくつかのタプルを抽出することです:
そして、私は次の構文を持つ再帰クエリを活用したいと思います:
WITH RECURSIVE cte_name(
CTE_query_definition -- non-recursive term
UNION
CTE_query definion -- recursive term
) SELECT * FROM cte_name;
ここで、p1
およびp3
は、さまざまなタイプのタプルにすることができます。つまり、私の再帰的でない用語は次のようになります。
SELECT * from TUPLES
再帰的な用語はデータから新しいタプルを生成しますが、既存のタプルを生成する必要はありません(UNION
のあるCTEとALL
のないCTE)。
SELECT
'ex' AS type_event,
t1.arg2 AS arg1,
t1.arg6 AS arg2,
null AS arg3,
null AS arg4,
null AS arg5,
null AS arg6
FROM cte_name t1
WHERE t1.type_event = 'Transfering'
AND t1.arg2 = t2.arg1
AND t1.arg6 = t2.arg2
UNION ALL
'ex' AS type_event,
t1.arg2 AS arg1,
t1.arg6 AS arg2,
null AS arg3,
null AS arg4,
null AS arg5,
null AS arg6
FROM cte_name t1
WHERE t1.type_event = 'Replacement'
AND t1.arg2 = t2.arg1
AND t1.arg6 = t2.arg2
UNION ALL
'ex' AS type_event,
t1.arg2 AS arg1,
t1.arg1 AS arg2,
null AS arg3,
null AS arg4,
null AS arg5,
null AS arg6
FROM cte_name t1
WHERE t1.type_event = 'ex'
ちなみに、WITH RECURSIVE
では、再帰的な要素がさまざまな選択の和集合である再帰的なステートメントを表現できません。これをC++/Java/Pythonでプログラムで実装する必要がない効率的なソリューションはありますか?これにより、すべてのデータがデータベースに「とどまる」ため、データを複数回シリアル化および非シリアル化する必要がなくなりますか?
TUPLES
の入力データの例:
+-------------+------+------+------+------+------+------+
| type_event | arg1 | arg2 | arg3 | arg4 | arg5 | arg6 |
+-------------+------+------+------+------+------+------+
| ex | A | B | null | null | null | null |
+-------------+------+------+------+------+------+------+
| Transfering | A | B | C | D | E | F |
+-------------+------+------+------+------+------+------+
| Replacement | G | H | I | J | K | L |
+-------------+------+------+------+------+------+------+
3番目と最後の反復後の予想される出力:
+-------------+------+------+------+------+------+------+
| type_event | arg1 | arg2 | arg3 | arg4 | arg5 | arg6 |
+-------------+------+------+------+------+------+------+
| ex | A | B | null | null | null | null |
+-------------+------+------+------+------+------+------+
| Transfering | A | B | C | D | E | F |
+-------------+------+------+------+------+------+------+
| Replacement | G | H | I | J | K | L |
+-------------+------+------+------+------+------+------+
| ex | B | F | null | null | null | null |
+-------------+------+------+------+------+------+------+
| ex | H | L | null | null | null | null |
+-------------+------+------+------+------+------+------+
| ex | B | A | null | null | null | null |
+-------------+------+------+------+------+------+------+
| ex | F | B | null | null | null | null |
+-------------+------+------+------+------+------+------+
| ex | L | H | null | null | null | null |
+-------------+------+------+------+------+------+------+
目的の再帰的な用語の3つの部分は同じCTEから行を選択するため、それらを単一のSELECTに変換できます。
SELECT ...
FROM cte_name t1
WHERE (t1.type_event = 'Transfering' AND t1.arg2 = t2.arg1 AND t1.arg6 = t2.arg2)
OR (t1.type_event = 'Replacement' AND t1.arg2 = t2.arg1 AND t1.arg6 = t2.arg2)
OR (t1.type_event = 'ex')
列の並べ替えは CASE式 で実行できます。
SELECT 'ex' AS type_event, -- same for all three
t1.arg2 AS arg1, -- same for all three
CASE t1.type_event
WHEN 'Transfering' THEN t1.arg6
WHEN 'Replacement' THEN t1.arg6
WHEN 'ex' THEN t1.arg1
END AS arg2,
...