0

サンプル データベース (ネストされたセット モデルのカテゴリ):

CREATE TABLE `category` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) NOT NULL DEFAULT '',
    `lft` int(11) NOT NULL,
    `rgt` int(11) NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

INSERT INTO category(name, lft, rgt) values("Primary", 0, 1000);
INSERT INTO category(name, lft, rgt) values("Secondary", 1, 500);
INSERT INTO category(name, lft, rgt) values("Tertiary", 2, 20);
INSERT INTO category(name, lft, rgt) values("Tertiary2", 21, 30);

次のように、下位の子カテゴリ (おそらく連結?) のすべての親を取得したい:

Primary > Secondary > Tertiary
Primary > Secondary > Tertiary2

BETWEEN lft AND rgt と CONCAT で遊んでいる以外に、私はかなり行き詰まっており、必要な結果を得るためのヒントと情報を使用できます。ありがとう!

SQL フィドル

4

2 に答える 2

2

次のクエリはどうですか?

SELECT 
  GROUP_CONCAT(parent.name SEPARATOR '/') as parent_name
FROM category AS node,
        category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.lft;

要求された出力を返します:

Primary
Primary > Secondary
Primary > Secondary > Tertiary
Primary > Secondary > Tertiary2

テスト可能 @ http://sqlfiddle.com/#!9/4f4e97/2

リーフノードのみが必要な場合

元の質問を正しく読んだ場合、期待される出力は次のようになります。

Primary > Secondary > Tertiary
Primary > Secondary > Tertiary2

上記のクエリを次のように少し変更することで、これも簡単に実現できます。

SELECT 
  GROUP_CONCAT(parent.name SEPARATOR '/') as parent_name
FROM category AS node,
        category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.lft, node.rgt
HAVING node.lft = (node.rgt - 1)
ORDER BY node.lft;

ただし、これはすべてのリーフノードが (本来あるべきように) rgt = lft + 1 であると仮定しています!!

テスト @ http://sqlfiddle.com/#!9/57acd4/1

于 2019-05-07T12:08:29.417 に答える
0

Mike Hillyer による階層データの管理に関するこの優れた記事をご覧ください。

データを構造化するだけでなく、Adjacency List モデルと Nested Set モデルのいくつかの違いを含め、データをクエリおよび操作する方法についても非常に優れた方法を説明しています。

  • テーブル構造
  • さまざまな方法でそれを照会する方法
    • ノード、パス、およびフル ツリーの結果の検索
  • 新しいデータの挿入の処理
  • データの削除の取り扱い

最後に、この記事は、このような結果を SQL で直接生成するという要件に明示的に答えていないことを認識しています。

Primary > Secondary > Tertiary
Primary > Secondary > Tertiary2

コストのかかるループやクエリの維持が非常に困難になることなく、これを行う適切な方法については、おそらくあまり良い読み物を見つけることができないでしょう。

通常、これはアプリケーション レベルで行われます。一般に、これらの言語の方がアプリケーション レベルに適しているからです (また、データをクエリできる場合は、このループを非常に簡単にする深さの値を生成できます)。

于 2014-05-13T23:25:21.670 に答える