質問
できません テーブルエイリアスを参照する 同じレベルの別のクエリ(または UNION
の別のレッグ)の1つのサブクエリから クエリ)。テーブルエイリアスは、クエリ自体とそのサブクエリにのみ表示されます。
できた LATERAL JOIN
。例:
groupbyを使用して配列内の最も一般的な要素を検索
レベルの最大数が少ない場合の解決策
ほんの一握りのレベル(知っている場合 最大)、簡単なクエリを使用できます:
-
LEFT JOIN
テーブル自体のn-1インスタンスへ -
COALESCE
を使用する およびCASE
ルートとハイトを特定するステートメント
SELECT p1.c AS child, COALESCE(p3.p, p2.p, p1.p) AS parent
,CASE
WHEN p3.p IS NOT NULL THEN 3
WHEN p2.p IS NOT NULL THEN 2
ELSE 1
END AS height
FROM parent p1
LEFT JOIN parent p2 ON p2.c = p1.p
LEFT JOIN parent p3 ON p3.c = p2.p
WHERE p1.c IN (3, 8)
ORDER BY p1.c;
これは標準SQLであり、4つのRDBMSすべてで機能するはずです。 タグを付けました。
任意の数のレベルの一般的なソリューション
再帰CTE を使用します @Kenのようにすでにアドバイスされています。
- 再帰的な脚で子供を飼う すべての行について、親のみを進めます。
- 外側の
SELECT
、height
が最大の行のみを保持します 子供1人あたり。
WITH RECURSIVE cte AS (
SELECT c AS child, p AS parent, 1 AS height
FROM parent
WHERE c IN (3, 8)
UNION ALL
SELECT c.child, p.p AS parent, c.height + 1
FROM cte c
JOIN parent p ON p.c = c.parent
-- WHERE c.height < 10 -- to safeguard against endless loops if necessary
)
SELECT DISTINCT ON (child) *
FROM cte
ORDER BY child, height DESC;
DISTINCT ON
Postgresに固有です 。説明:
各GROUPBYグループの最初の行を選択しますか?
残りはOracleでも同様に機能します そしてSQLite 、ただし、CTEをサポートしないMySQLにはありません。
SQLフィドル 両方を示しています。