2017-11-13 4 views
2

私はユーザとの階層構造に対してどのようにして成功したクエリを達成できるのだろうか。私は同様の質問を掲示しましたが、今は幹部だけが彼らに割り当てられたcostumersを持つことができる構造が変更されました。階層クエリ

ユーザーのこのレベルがあります。

  1. ディレクター
  2. マネージャー
  3. エグゼクティブ

例表USERS:

ID username privilege parent_ID 
1  Director1 1   null 
2  Director2 1   null 
3  Manager1 2   1 
4  Manager2 2   1 
5  Manager3 2   2 
6  Executive1 3   3 
7  Executive2 3   3 
8  Executive3 3   4 
9  Executive4 3   4 
10 Executive5 3   5 
11 Executive6 3   5 

そして、彼らは彼らの「のcostumersを持っています"

ID name User_ID 
1 c1 11 
2 c2 10 
3 c3 10 
4 c4 9 
5 c5 8 
6 c6 7 
7 c7 6 

私の問題は、すべてのユーザーが、ルールが彼らということでしょうこれは、それらが許可されているだけのcostumersを見ることができますように、私は作るべき参加の種類にある

例テーブルのcostumers彼らの下にある幹部からのコスチュームだけを見ることができ、エグゼクティブは自分のコスチュームだけを見ることができます。上図の

例えば

Diagram

、ユーザーが自分のcostumersを確認することだった場合、彼が表示されるはずです。

Director1:C7、C6、C5、C4

Director2:C3、C2、 C1

マネージャ1:C7、C6

マネージャ2:C5、C4

マネージャ3:C3、C2、C1

と幹部だけが自分のcostumersを参照してください。 https://dev.mysql.com/doc/refman/8.0/en/with.html

WITH RECURSIVE h AS (
    SELECT ID FROM USERS WHERE ID = ? 
    UNION 
    SELECT ID FROM USERS AS u JOIN h ON u.parent_ID = h.ID 
) 
SELECT c.* 
FROM h 
JOIN COSTUMERS AS c ON c.User_ID = h.ID; 

あなたがまだのMySQL 5.7以前を使用している場合は、あなたがぎこちなくより多くのそれを実行する必要があります。

答えて

2

この問題を解決する適切な方法は、MySQL 8.0で来ている再帰CTEクエリ、です。 1つの利点があります。階層の最大深度は固定されています。

SELECT c.* 
FROM (
    SELECT e.ID FROM USERS AS e 
    WHERE e.ID = ? 
    UNION ALL 
    SELECT e.ID FROM USERS AS e 
    JOIN USERS AS m ON e.parent_ID = m.ID 
    WHERE m.ID = ? 
    UNION ALL 
    SELECT e.ID FROM USERS AS e 
    JOIN USERS AS m ON e.parent_ID = m.ID 
    JOIN USERS AS d ON m.parent_ID = d.ID 
    WHERE d.ID = ? 
) AS h 
JOIN COSTUMERS AS c ON c.User_ID = h.ID; 

私は、階層をClosure Tableのような別のデザインに再構築することはできないと考えています。あなたは他のデザインに興味を持っている場合でも、What is the most efficient/elegant way to parse a flat table into a tree?

それとも私のプレゼンテーション​​3210

それとも私の著書SQL Antipatterns: Avoiding the Pitfalls of Database Programmingに私の答えを参照してください。

+0

ありがとう、あなたはMYSQL 8の使用に関するアドバンテージを知っていますか?私はこれにdev版を使うべきですか?あまりにも多くのリソースを消費するバージョン5.7は、それを使用したり、8.0を待っていても良いアイデアかもしれませんか? –

+0

また、あなたのプレゼンテーションを読んでいる、私はすべての私のデータベースを構成しているフェーズにあるので、私はまだ変更を加えることができるので、何かを再構成する範囲の外にはありません。テーブルを閉める方が良いでしょうか? –

+0

MySQL 8.0は現在リリース候補のステータスです。プロダクションで使用する準備ができているかどうかを判断するのは時期尚早です。したがって、慎重にテストする必要があります。 MySQLコミュニティには、新しい「メジャー」バージョン(「.20」リリース、つまりMySQL 8.0.20)が採用されるまで、それを避けるという冗談があります。それから、大きなバグと荒いビットが解決されるはずです。このルールは、以前のMySQL開発担当ディレクターから来ています。https://www.flamingspork.com/blog/2013/08/01/stewarts-dot-twenty-rule/ –