2014-10-06 180 views
0

第一臺嵌套SELECT + INNER JOIN

CREATE TABLE IF NOT EXISTS `city_node` (
`node_id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
`title` varchar(50) NOT NULL, 
`parent_node_id` int(10) unsigned NOT NULL DEFAULT '0', 
`lft` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Nested set info ''left'' value', 
`rgt` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Nested set info ''right'' value', 
`depth` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Depth = 0: no parent', 
PRIMARY KEY (`node_id`), 
KEY `parent_node_id` (`parent_node_id`), 
KEY `lft` (`lft`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=26; 

和數據

INSERT INTO `city_node` (`node_id`, `title`, `parent_node_id`, `lft`, `rgt`, `depth`) VALUES 
(1, 'Great Britain', 0, 1, 20, 0), 
(3, 'England', 1, 2, 9, 1), 
(7, 'Scotland', 1, 16, 19, 1), 
(8, 'Edinburgh', 7, 17, 18, 2), 
(9, 'Wales', 1, 10, 15, 1), 
(10, 'Cardiff', 9, 11, 12, 2), 
(11, 'London', 3, 3, 4, 2), 
(12, 'Birmingham', 3, 5, 6, 2), 
(13, 'Germany', 0, 21, 26, 0), 
(14, 'Stuttgart', 13, 22, 23, 1), 
(15, 'Newport', 9, 13, 14, 2), 
(16, 'Munich', 13, 24, 25, 1), 
(17, 'Israel', 0, 27, 32, 0), 
(18, 'Tel Aviv', 17, 28, 29, 1), 
(19, 'Ashdod', 17, 30, 31, 1), 
(20, 'USA', 0, 33, 38, 0), 
(21, 'New York', 20, 34, 35, 1), 
(24, 'Liverpool', 3, 7, 8, 2), 
(25, 'Detroit', 20, 36, 37, 1); 

二表

CREATE TABLE IF NOT EXISTS `city_node_entity` (
    `node_id` int(10) NOT NULL, 
    `entity` tinyint(3) unsigned NOT NULL DEFAULT '1', 
    KEY `node_id` (`node_id`,`entity`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

和數據

INSERT INTO `city_node_entity` (`node_id`, `entity`) VALUES 
(11, 1), 
(12, 1), 
(16, 1), 
(19, 1); 

我想與實體1和它的祖先節點,這樣

大不列顛
--England
----倫敦
----伯明翰
德國
--Munich
以色列
--Ashdod

所以,我的查詢是

SELECT DISTINCT(node_ext.node_id), node_ext.* 
FROM city_node_entity AS entity 
LEFT JOIN city_node AS node 
    ON entity.node_id = node.node_id 
LEFT JOIN city_node AS node_ext 
    ON node_ext.lft <= node.lft AND node_ext.rgt >= node.rgt 
WHERE entity.entity = 1 
ORDER BY node_ext.lft 

但解釋顯示 - 使用的地方;使用索引;使用臨時;使用filesort

是否有任何其他查詢獲得相同的結果,但更少的[額外]?

+0

MySQL不支持遞歸查詢......多少級深將這個去了? – 2014-10-06 17:42:46

+0

深層次沒有限制 – kedoff 2014-10-06 17:49:18

+0

那麼這是不可能的在mysql中...有沒有支持遞歸查詢..如果我知道有多少級別,那麼它是可能的但只有通過該 – 2014-10-06 17:50:22

回答

0

你可以爲遞歸查詢做的唯一事情就是用每個父/子的連接來運行....因爲你的第二張表是真實的城市名稱而你想向後工作,你可以這樣做。 ..只是增加更多的連接,直到所有的結果都爲空,你將有自己完整的樹

SELECT node.title AS child, t2.title as parent1, t3.title as parent2, t4.title as parent3 
FROM city_node_entity AS entity 
LEFT JOIN city_node AS node ON entity.node_id = node.node_id 
LEFT JOIN city_node AS t2 ON t2.node_id = node.parent_node_id 
LEFT JOIN city_node AS t3 ON t3.node_id = t2.parent_node_id 
LEFT JOIN city_node AS t4 ON t4.node_id = t3.parent_node_id; 

Fiddle Demo

+0

這不是相當破壞點使用嵌套集? – Strawberry 2014-10-06 19:35:21

+0

@Strawberry考慮MySQL沒有遞歸功能,這是最好的,你可以只在MySQL做 – 2014-10-06 19:38:22

+0

但我認爲嵌套集應該避免遞歸 - 也許我誤解了這個問題:-( – Strawberry 2014-10-06 21:29:44