メインコンテンツにスキップ
モジュール 5 · レッスン 2 / 4コース内の 18/57~10 min
モジュールのレッスン (2/4)

Self-JOIN: それ自体とのテーブル

場合によっては、あなたが通過したい関係が 2 つの間の関係ではないことがあります** 異なるテーブルですが、**同じテーブルの行**の間です。典型的な例: 「カテゴリ→サブカテゴリ」階層。親と子は両方とも次の行になります。 同じ categories テーブルが parent_id によってリンクされています。

1 つの行 (子) と「その」他の行 (親) を一緒に読み取るには、 自己結合: 同じテーブルが FROM に 2 回表示されます。 さまざまな別名。

構文

SQL
SELECT colonne
FROM   tabella AS alias_a
JOIN   tabella AS alias_b ON alias_a.foreign_key = alias_b.id;

エイリアスは 必須です: AS a / AS b を省略すると、PostgreSQL にはエイリアスがありません。 name または id と書くときに、2 つのコピーのどちらを意味するのかを知る方法です。

SQL
-- Ogni sotto-categoria con il nome della categoria padre:
SELECT child.name  AS subcategory,
       parent.name AS category
FROM   categories AS child
JOIN   categories AS parent ON child.parent_id = parent.id;

平易な英語で読む: 「child という名前の categories の行を取得し、 それぞれについて、parent という名前の categories の行を見つけます。その id は 子のparent_id「.

結果にはルート カテゴリ (parent_id = NULL を持つカテゴリ) が除外されます。 INNER JOIN は一致しない行をスキップするためです。含めたい場合は、 LEFT JOIN を使用してください。

LEFT と自己結合して「ルーツも維持」

SQL
-- Tutte le categorie, con nome del padre o NULL se sono radice:
SELECT child.name AS category,
       parent.name AS parent
FROM   categories AS child
LEFT JOIN categories AS parent ON child.parent_id = parent.id;

これで、parent = NULL を含む 9 行 (データセット内のすべてのカテゴリ) が取得されました。 3つの根のために。

自己結合による集約

GROUP BY と非常によく組み合わせて、「それぞれの子が何人いるか」を尋ねます。 親が持っている":

SQL
SELECT p.name AS parent_category,
       COUNT(c.id) AS children
FROM   categories AS p
LEFT JOIN categories AS c ON c.parent_id = p.id
WHERE  p.parent_id IS NULL          -- solo le radici
GROUP BY p.name
ORDER BY p.name;

2 つの重要な詳細に注意してください。

  1. WHERE p.parent_id IS NULL は JOIN の前** をフィルターします。 「左側のテーブル」としてルートします。
  2. COUNT(c.id) (COUNT(*) ではありません) は、子のないルートに対して 0 を返します。 一方、LEFT JOIN 行には次があるため、COUNT(*) は 1 を返します。 NULL。

自分で試してみてください

運動#sql.m5.l2.e1
試行回数: 0読み込み中…

それぞれのソット カテゴリ (parent_id NOT NULL に対するカテゴリ) ごとに、ソット カテゴリの名前とカテゴリの名前が最もよく知られています。 Due Colonne: サブカテゴリー、カテゴリー。カテゴリごとの Ordina、サブカテゴリごとのポイ。

エディターを読み込み中…
ヒントを表示

自己結合の条件は child.parent_id =parent.id です。

3 回の試行後に解決策が利用可能になります

復習演習

運動#sql.m5.l2.e2
試行回数: 0読み込み中…

カテゴリーごとの基数 (parent_id IS NULL)、ほとんどの名前とそのカテゴリーの数。ドゥエコロン:名前、子供たち。名前の通りオルディナ。最終的なラディセ センザ フィリエ コン 0 が含まれます。

エディターを読み込み中…
ヒントを表示

カテゴリに対して LEFT JOIN を 2 回実行します (親にはエイリアス p、子には c)。子のないルートで 0 を取得するには、COUNT(*) ではなく COUNT(c.id) を使用します。

3 回の試行後に解決策が利用可能になります