階層データでMySQLを使用することについて調査したため(現在、私のテーブルは隣接リストモデルを使用しています)、親IDを送り返し、PHPで同じ関数を再帰するループを介してブレッドクラムを取得していますが、これによりクエリが発生します毎回。そこで、_construct メソッドを作成してクエリを 1 回起動し、参照できるオブジェクトを返すことで改善したいと考えています。
これを行うために、ネストされたセット、パスの列挙 (実体化されたパス)、およびクロージャー テーブルについていくつかの調査を行いました。
私は具体化された道を選びました。
私のSQL
SELECT t1.*
FROM menu t1
WHERE t1.menu_id IN (
SELECT TRIM(REPLACE(t2.Lineage,'/',',')) as CAT_IDD
FROM menu t2
WHERE t2.page_id = 52
)
私のテーブルはそのようなものです。テストできるようにダンプに貼り付けます...
構造
CREATE TABLE IF NOT EXISTS `menu` (
`menu_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`menu_text` varchar(255) NOT NULL DEFAULT 'NEW !!!',
`menu_alt_text` varchar(255) DEFAULT NULL,
`menu_alt_location` varchar(255) DEFAULT NULL,
`page_id` int(11) unsigned NOT NULL DEFAULT '0',
`parent_menu_id` int(11) unsigned NOT NULL DEFAULT '0',
`lineage` varchar(255) DEFAULT NULL,
`menu_display_order` int(11) unsigned NOT NULL DEFAULT '1',
`menu_display` tinyint(1) unsigned NOT NULL DEFAULT '1',
`site_short_code` varchar(20) NOT NULL DEFAULT 'DEFAULT',
`menu_can_delete` tinyint(1) NOT NULL DEFAULT '1',
`user_id` int(11) unsigned NOT NULL DEFAULT '0',
`opens_in_new_window` tinyint(1) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`menu_id`),
KEY `site_short_codee` (`site_short_code`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='This displays the menu/navigation of the site' AUTO_INCREMENT=75 ;
データを挿入する
INSERT INTO `menu` (`menu_id`, `menu_text`, `menu_alt_text`, `menu_alt_location`, `page_id`, `parent_menu_id`, `lineage`, `menu_display_order`, `menu_display`, `site_short_code`, `menu_can_delete`, `user_id`, `opens_in_new_window`)
VALUES (1, 'Home', 'opens in same window', 'none', 1, 0, '0', 1, 1, 'site1', 0, 0, 0),
(41, 'About Us', 'About Us, opens in same window', 'none', 42, 0, '0', 4, 1, 'site1', 1, 43, 0),
(42, 'Menu 3', 'Menu 3, opens in same window', 'none', 43, 0, '0', 30, 1, 'site1', 1, 43, 0),
(43, 'Menu 4', 'Menu 4 templates, opens in same window', 'none', 44, 42, '1/42', 9, 1, 'site1', 1, 43, 0),
(44, 'Menu 5', 'Menu 5, opens in same window', 'none', 45, 42, '1/42', 3, 1, 'site1', 1, 43, 0),
(45, 'Menn 6', 'Menu 6, opens in same window', 'none', 46, 42, '1/42', 6, 1, 'site1', 1, 43, 0),
(46, 'Menu 7', 'Menu 7, opens in same window', 'none', 47, 0, '0', 43, 1, 'site1', 1, 43, 0),
(47, 'Menu 8', 'Menu 8, opens in same window', 'none', 48, 46, '1/46', 3, 1, 'site1', 1, 43, 0),
(48, 'Menu 9', 'Menu 9, opens in same window', 'none', 50, 46, '1/46', 6, 1, 'site1', 1, 43, 0),
(49, 'Menu 10', 'Menu 10, opens in same window', 'none', 53, 48, '1/46/48', 9, 1, 'site1', 1, 43, 0),
(50, 'Menu 11', 'Menu 11, opens in same window', 'none', 49, 46, '1/46', 12, 1, 'site1', 1, 43, 0),
(51, 'Menu 12', 'Menu 12, opens in same window', 'none', 51, 48, '1/46/48', 15, 1, 'site1', 1, 43, 0),
(52, 'Menu 13', 'Menu 13, opens in same window', 'none', 52, 48, '1/46/48', 18, 1, 'site1', 1, 43, 0),
(53, 'Menu 14, 'Menu 14, opens in same window', 'none', 70, 0, '0', 7, 1, 'site1', 1, 43, 0),
(54, 'Release Dates', 'Release Dates, opens in same window', 'none', 56, 53, '1/53', 12, 1, 'site1', 1, 43, 0),
(55, 'Clients', 'Clients, opens in same window', 'none', 57, 0, '0', 65, 1, 'site1', 1, 43, 0),
(56, 'Menu 145 Clients', 'Menu 145 clients, opens in same window', 'none', 74, 55, '1/55', 3, 1, 'site1', 1, 43, 0),
(57, 'ffff', 'ffff, opens in same window', 'none', 59, 55, '1/55', 6, 1, 'site1', 1, 43, 0);
これにより、リネージュの menu_ids のリストが返されます
SELECT TRIM(REPLACE(t2.Lineage,'/',',')) as CAT_IDD
FROM menu t2
WHERE t2.page_id = 52
ただし、上記のサブクエリとして使用すると、1 行しか返されません。3を返すために必要です。ネストJOINも使用してみました...
うーん、どんなアイデアでも大歓迎です。
ありがとう
そして私
------ EDIT 自分の質問に答える
SELECT t1.*
FROM menu t1, menu t2
WHERE
t2.page_id = 52
AND
FIND_IN_SET (
t1.menu_id, t2.Lineage
)
これは私にとってはうまくいくようです...これが他の誰かに役立つなら、そう願っています。区切り文字をコンマに変更しました
ありがとう