1

私は(変更できない)データベースを持っています。1つのテーブルは次のようになります。

| ID:integer | fk:integer | next:[integer array] |
--------------------------------------------------
| 1          | 711        | {4}                  |
| 2          | 712        | {6}                  |
| 3          | 788        |                      |
| 4          | 799        | {7}                  |
--------------------------------------------------

ここで、最初の行としてデータを、次の行として、整数配列( ) 内にあるID = 1すべてのデータを含む 1 つのクエリを定義して、クエリが返すようにします。IDnext{4}

| ID:integer | fk:integer | next:[integer array] |
--------------------------------------------------
| 1          | 711        | {4}                  |
| 4          | 799        | {7}                  |
--------------------------------------------------

しかし、その後停止するため、指定された要素とその要素を持つ要素のみがID生成されnextます。

私は試してみました。このように、しかし私はそれを動作させることができません:

SELECT * FROM tablenm WHERE ID = ANY(SELECT next FROM tablenm WHERE ID = 1) AND ID = 1

私が使用している現在の回避策は、最初に次のクエリを使用することです。

SELECT * FROM tablenm WHERE ID = 1

次に、配列内の各要素に対して、IDプログラムでループ内の s を使用して同じクエリを実行しますが、これは汚いハックのように見え、1 つの SQL ステートメントでこれに対する解決策があることを願っています。

4

2 に答える 2

2

これには再帰は必要ありません。配列のネストを解除するだけです。

これはうまくいくはずです:

select * from tablename where id=1
UNION ALL
select * from tablename where id
  in (select unnest(next) from tablename where id=1);
于 2013-09-30T19:30:16.137 に答える
2

= ANY(array)JOIN 条件で使用できます。

SELECT t2.*
FROM   tbl t1
JOIN   tbl t2 ON t2.id = ANY(t1.next)
              OR t2.id = t1.id  -- add first row
WHERE  t1.id = 1                -- enter id to filter on once
ORDER  BY (t2.id <> t1.id);     -- "first row the data with ID = ?"

最速である必要があります。
@Daniel が説明したように、このフォーム (クエリなど) には最初の行が 1だけ含まれます。

「より短いクエリ」が必要な場合:

SELECT t2.*
FROM   tbl t1
JOIN   tbl t2 ON t2.id = ANY(t1.next || t1.id) -- append id to array
WHERE  t1.id = 1;  -- not sure if you need ORDER BY

これは最初の形式と同等のものに内部的に展開されるため、最初の形式よりも短くなりますが、高速ではありません。でパフォーマンスをテストしEXPLAIN ANALYZEます。

次の理由により、nextも になる可能性があることに注意してください。NULL

SELECT NULL::int[] || 5  --> '{5}'
于 2013-09-30T22:42:17.137 に答える