MySQL クエリツリー構造1. ツリー構造についてこのタイプの構造のデータは通常、テーブル構造内に id や parentId などの自己関連付けフィールドを必要とします。場合によっては、クエリの効率を向上させるために、index などの冗長フィールドを追加できます。index の値は、すべての親ディレクトリの id 文字列のセットです。 ツリー構造データの組み立てについては、プログラム内で再帰的に完全なツリーを構築する書き方が一般的です。単純にSQLを使用する方法はあまり使われません。以下に2つの方法の例を示します。 2. MySQLでカスタム関数を定義する方法MySQL カスタム関数とは: 集計関数、日付関数などはすべて MySQL 関数です。ここで定義する関数は、それらと同じように使用できますが、定義されたデータベースでのみ使用できます。カスタム関数はストアド プロシージャに似ていますが、違いは、関数は 1 つの値のみを返し、結果セットを返すことができないことです。 2.1 テストデータを作成するテーブル「tree」を作成します( `id` bigint(11) NOT NULL, `pid` bigint(11) NULL デフォルト NULL, `name` varchar(255) 文字セット utf8 COLLATE utf8_general_ci NULL デフォルト NULL, BTREE を使用した主キー (`id`) ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; `tree` VALUES (1, 0, '中国') に INSERT INTO します。 `tree` VALUES (2, 1, '四川省') に INSERT INTO します。 `tree` VALUES (3, 2, '成都') に INSERT INTO します。 `tree` VALUES (4, 3, '武侯区') に INSERT INTO します。 `tree` VALUES (5, 4, 'Red Archway') に INSERT INTO します。 INSERT INTO `tree` VALUES (6, 1, '広東省'); INSERT INTO `tree` VALUES (7, 1, '浙江省'); `tree` VALUES (8, 6, 'Guangzhou') に INSERT INTO します。 2.2 ノードの下にあるすべての子ノードを取得する関数 `GET_CHILD_NODE`(rootId varchar(100)) を作成します。 戻り値 varchar(2000) 始める str varchar(2000) を宣言します。 cid varchar(100) を宣言します。 str = '$' を設定します。 cid = rootId を設定します。 cidがnullでない場合に実行 SET str = concat(str, ',', cid); group_concat(id) を tree から cid に選択します。ここで、FIND_IN_SET(pid, cid); 終了しながら; 文字列を返します。 終わり カスタム関数の呼び出し FIND_IN_SET(id, GET_CHILD_NODE(2))のツリーから*を選択します。 2.3 ノードのすべての親ノードを取得する関数 `GET_PARENT_NODE`(rootId varchar(100)) を作成します。 戻り値 varchar(1000) 始める fid varchar(100) default '' を宣言します。 str varchar(1000) default rootIdを宣言します。 rootIdがnullでない場合に SET fid =(SELECT pid FROM tree WHERE id = rootId); fidがnullでない場合 SET str = concat(str, ',', fid); rootId = fid を設定します。 それ以外 rootId = fid を設定します。 終了の場合; 終了しながら; str を返します。 終わり カスタム関数の呼び出し FIND_IN_SET(id, GET_PARENT_NODE(5))のツリーから*を選択します。 3. Oracleデータベース方式再帰ツリー クエリを完了するには、start with connect by prior ステートメントを使用するだけです。詳細については、関連情報を参照してください。 4. プログラムコードは再帰的にツリーを構築するここでは完全なコードは示しません。再帰メソッドは非常にシンプルです。まず、すべてのツリー ノードを見つけ、次に TreeNode クラスの add メソッドを使用してすべての子ノードを再帰的に追加します。コアコードは次のとおりです。 パブリッククラス TreeNodeDTO { プライベート文字列ID; プライベート文字列親ID; プライベート文字列名; プライベートList<TreeNodeDTO> children = new ArrayList<>(); パブリック void add(TreeNodeDTO ノード) { if ("0".equals(node.parentId)) { this.children.add(ノード); } そうでない場合 (node.parentId.equals(this.id)) { this.children.add(ノード); } それ以外 { //add() を再帰的に呼び出して子ノードを追加します for (TreeNodeDTO tmp_node : children) { tmp_node.add(ノード); } } } } 5. hashMapを使用すると、1回の走査のみで済みますツリー生成を完了できます: 5つ星の推奨 リスト<TreeNodeDTO> リスト = dbMapper.getNodeList(); ArrayList<TreeNodeDTO> rootNodes = 新しいArrayList<>(); Map<Integer, TreeNodeDTO> map = new HashMap<>(); (TreeNodeDTO ノード: リスト) { ノードをマップします。 整数の親Id = node.getParentId(); // 親ノードがあるかどうかを判定します(親ノードがない場合は親メニューです) (親IDが'0'に等しい)の場合 ルートノードを追加します。 // 親メニューではないメニューを検索し、その親メニュー ID をコレクションに含めます } そうでない場合 (map.containsKey(parentId)){ map.get(parentId).getChildren().add(ノード); } } ツリー構造情報を含むMySQLクエリOracleには、ツリー構造情報を直接照会できる関数アプリケーションがあります。たとえば、次のツリー構造を持つ組織メンバー構造がある場合、いずれかのノードの下にあるすべてのノード情報を照会したい場合、 Oracleでは、次の構文を使用して直接クエリを実行できます。まずはCONNECT BY PRIOORから しかし、MySQL にはそのような構文はありません。このようなデータ構造情報も照会したい場合はどうすればよいでしょうか?独自の関数を定義できます。上記の情報をデータベースに初期化します。まず、この情報を格納するテーブルを作成します。ID には自身の ID 情報が、PARENT_ID には親の ID 情報が格納されます。 テーブル「company_inf」を作成します( `ID` varchar(32) COLLATE utf8mb4_unicode_ci デフォルト NULL, `NAME` varchar(255) COLLATE utf8mb4_unicode_ci デフォルト NULL, `PARENT_ID` varchar(32) COLLATE utf8mb4_unicode_ci デフォルト NULL ) 次にテーブル内の情報を初期化します company_inf に VALUES ('1','ゼネラルマネージャー Wang Damazi','1') を挿入します。 company_inf に VALUES ('2','R&D マネージャー Liu Daquezi','1') を挿入します。 company_inf に VALUES ('3','営業部長 Ma Erlangzi','1') を挿入します。 company_inf に VALUES ('4','財務マネージャー Zhao Santuozi','1') を挿入します。 company_inf に VALUES ('5','秘書従業員 J','1') を挿入します。 company_inf に VALUES ('6','R&D チームリーダー Wu Dabangchui','2') を挿入します。 INSERT INTO company_inf VALUES ('7','Zheng Laoliu、R&Dグループ2の責任者','2'); company_inf に VALUES ('8','営業担当者 G','3') を挿入します。 company_inf に VALUES ('9','営業担当者 H','3') を挿入します。 company_inf に VALUES ('10','財務担当者 I','4') を挿入します。 company_inf に VALUES ('11','開発者 A','6') を挿入します。 company_inf に VALUES ('12','開発者 B','6') を挿入します。 company_inf に値 ('13'、'開発者 C'、'6') を挿入します。 company_inf に値 ('14'、'開発者 D'、'7') を挿入します。 company_inf に VALUES ('15','Developer E','7') を挿入します。 company_inf に値 ('16'、'開発者 F'、'7') を挿入します。 例えば、R&DマネージャーのLiu Daquziの配下の従業員全員を照会したい場合、Oracleで次のように記述できます。 選択* T_PORTAL_AUTHORITY より ID='1' で開始 以前のIDで接続 = PARENT_ID MySQLでは、次のカスタム関数が必要です。 関数 getChild(parentId VARCHAR(1000)) を作成します。 VARCHAR(1000)を返します 始める oTemp VARCHAR(1000) を宣言します。 oTempChild VARCHAR(1000) を宣言します。 oTemp を '' に設定します。 oTempChild = 親IDを設定します。 oTempChildがnullでない場合に実行 oTemp != '' の場合 oTemp を連結して設定します (oTemp,',',oTempChild); それ以外 oTemp = oTempChild を設定します。 終了の場合; SELECT group_concat(ID) INTO oTempChild FROM company_inf where parentId<>ID and FIND_IN_SET(parent_id,oTempChild)>0; 終了しながら; oTemp を返します。 終わり すると、このようにクエリできます company_inf から * を選択し、 FIND_IN_SET(ID,getChild('2')); 現時点では、クエリをチェックして取得した情報は、Liu Daquzi の配下の従業員情報すべてです。 上記は私の個人的な経験です。参考になれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: CentOS 8 に Docker をインストールする詳細なチュートリアル
>>: Vue.js アプリケーションのパフォーマンス最適化分析 + ソリューション
目次1. 浅いコピー1. Object.assign(ターゲット、ソース、ソース...) 2. スプ...
Linux コンピュータには 2 つの時間があります。1 つはハードウェア時間 (BIOS に記録さ...
目次仮想DOMとは何ですか?なぜ仮想DOMが必要なのでしょうか?仮想 DOM はどのようにして実際の...
テーブルデータを作成する テーブル `praise_info` を作成します ( `id` bigi...
関連する知識ポイント親コンポーネントから子コンポーネントに値を渡す子コンポーネントから親コンポーネン...
序文私は、Web サイトのフロントエンド パフォーマンス最適化のための JavaScript と C...
CSS を使用してすべての子要素を再帰的に選択するにはどうすればよいですか?以下の記事では、CSS ...
最近、MySQL を使っています。Linux での mysql-installation という記事...
ここ数日、dockerでSpring Bootアプリケーションを実行する方法を勉強してきました。以前...
問題の説明プロジェクトに取り組んでいるときに、タブ バーの切り替え効果を作成する必要がある場合があり...
1. Pythonは起動時に自動的に実行されますPython の自己起動スクリプトがauto.pyで...
1 Dockerサービスを開始するまず、docker サービスを開始する方法を知っておく必要がありま...
次のような効果がよく見られます。 そうです、ページ上でよく使われる「展開と折りたたみ」のインタラクシ...
nginx ログは filebeat によって収集され、logstash に渡され、logstash...
Docker を正式に使用する前に、まず Docker でよく使用されるコマンドに慣れておきましょう...