2017-12-18 14 views
0

テーブルの階層がある場合、親テーブルの親のIDへの参照を含むテーブル内の各アイテムは、そのツリーを単一の)木としてSQLクエリ?sql階層テーブルからツリーを取得

  • specyのように見える(ID、名前、属)
  • 属(ID、名前、家族)
  • 家族(ID、名前)

何か:

SELECT * 
FROM specy 
JOIN genus ON genus.id=specy.genus 
JOIN family ON genus.family=family.id 

しかし、それが構文的に正しい場合であっても、このファミリの各属についてファミリフィールドを持つデータセット、およびファミリフィールドと属フィールドの両方を返さないでしょうかその属のそれぞれの特定のために?

SQLは階層ツリーを直接(簡単に)返すことができますか、別の言語で処理する必要があるデータセットだけを返すことができますか?

答えて

1

はい、SQLはcommon table expressions (CTEs)を使用して階層データを返すことができますが、すべてのデータベースがCTEをサポートしているわけではありません。構文は次のとおりです。

WITH [RECURSIVE] with_query [, ...] 
SELECT... 

例:

WITH RECURSIVE table1 (n, fact) AS 
(SELECT col1+1, col1*col2 FROM table1) 
SELECT * FROM table1; 
+0

のMySQL 8.0 +が...これをサポートしていますが、MySQL 8.0は、生産ジェットのための準備ができていない..です –

+0

MariaDB - MySQLのクローン - 10.2以降は、CTEを行うことができます。 –

+0

これは本当に、各行に重複した 'family'列と' genus'列を生成せずに3つのテーブルを結合する方法の問題に対処していますか? – Barmar

0

あなたはあなたがしてから重複を置き換えるために、ユーザ変数を使用し、家族や属で結果を注文することができ、冗長な情報を表示したくない場合前の行に空白があります。彼らが変わったときには、家族名と属名だけが表示されます。

SELECT CASE WHEN f.id = @prev_family THEN '' ELSE f.name END AS family, 
     CASE WHEN g.id = @prev_genus THEN '' ELSE g.name END AS genus, 
     s.name AS species 
FROM specy AS s 
JOIN genus AS g ON s.genus = g.id 
JOIN family AS f ON g.family = f.id 
CROSS JOIN (SELECT @prev_family := 0, @prev_genus := 0) AS vars 
ORDER BY f.id, g.id, s.id