0

我对将 MySQL 与分层数据一起使用进行了一些调查,(目前我的表使用邻接列表模型)所以我通过一个循环获取面包屑,将父 ID 发送回并在 PHP 中重新诅咒相同的函数,但这会触发一个查询每一次。所以现在我想通过创建一个 _construct 方法来触发一次查询并返回一个我可以引用的对象来改进。

为此,我对嵌套集、路径枚举(物化路径)和闭包表进行了一些研究。

我选择了物化路径。

我的 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);

这将返回 linage 中的 menu_ids 列表

    SELECT TRIM(REPLACE(t2.Lineage,'/',',')) as CAT_IDD
    FROM menu t2
    WHERE t2.page_id = 52

但是,当用作上面的子查询时,它只返回 1 行。我需要它来返回 3。我也尝试过使用嵌套 JOIN ......

嗯,任何想法将不胜感激。

谢谢

和我

------ 编辑回答自己的问题

SELECT t1.* 
FROM menu t1, menu t2
WHERE 
t2.page_id = 52
AND
FIND_IN_SET (
      t1.menu_id, t2.Lineage
)

这似乎对我有用......如果这对其他人有帮助,我希望如此。我将分隔符更改为逗号

谢谢

4

1 回答 1

0

好的,我认为这项工作可以找到历史......

SELECT t1.* 
FROM menu t1, menu t2
WHERE 
t2.page_id = 52
AND
FIND_IN_SET (
     t1.menu_id, t2.Lineage
)

如果这对其他人有帮助,我希望如此。我在血统字段的数据中将分隔符更改为逗号...

谢谢

于 2013-04-26T05:17:26.497 回答