MySQL in子句枚举表层次结构中的路径

时间:2013-04-25 12:26:15

标签: mysql nested set hierarchy

我对使用MySQL和Hierarchical数据进行了一些调查,(目前我的表使用了邻接列表模型)所以我通过一个循环发送了一个痕迹,发送了父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。 我也尝试过使用Nest JOIN ......

嗯,任何想法都会受到赞赏。

由于

岸堤

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

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

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

由于

1 个答案:

答案 0 :(得分:0)

好的我认为这可以找到历史......

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

如果这有助于其他任何人,我希望如此。我将分隔符更改为沿袭字段数据中的逗号...

由于