我使用以下SQL生成分层数据,并努力弄清楚如何让孩子按排序顺序ID值进行排序。任何关于如何欣赏的建议。请注意,这不是我的SQL,它取自我已修改的OpenCart的类别列表页面。我尝试将排序顺序添加到几个地方,但似乎没有任何区别。我想要的输出是显示
| PAGE_ID | NAME | PARENT_ID | SORT_ORDER |
|---------|----------------------------|-----------|------------|
| 75 | Index4 | 0 | -7 |
| 60 | Index | 0 | 0 |
| 68 | Index > Sub6 | 60 | -6 |
| 61 | Index > Sub1 | 60 | 1 |
| 65 | Index > Sub1 > SubSub2 | 61 | 4 |
| 64 | Index > Sub1 > SubSub1 | 61 | 6 |
| 67 | Index > Sub5 | 60 | 1 |
| 62 | Index > Sub2 | 60 | 2 |
| 63 | Index > Sub3 | 60 | 5 |
| 69 | Index > Sub3 > SubSub3 | 63 | 1 |
| 71 | Index > Sub3 > SubSub5 | 63 | 2 |
| 72 | Index > Sub3 > SubSub4 | 63 | 5 |
| 70 | Index > Sub3 > SubSub6 | 63 | 9 |
| 66 | Index > Sub4 | 60 | 7 |
| 74 | Index3 | 0 | 1 |
| 73 | Index2 | 0 | 4 |
请注意,树的每个子子集都是根据sort_order
列单独排序的,因此Index
的排序顺序不会影响Sub1
,{{1} }或Sub2
这些都不会对Sub3
,SubSub1
或SubSub2
SubSub3
查询1 :
DROP TABLE IF EXISTS `oc_page`;
CREATE TABLE `oc_page` (
`page_id` int(11) NOT NULL AUTO_INCREMENT,
`parent_id` int(11) NOT NULL DEFAULT '0',
`sort_order` int(3) NOT NULL DEFAULT '0',
`status` tinyint(1) NOT NULL,
`date_added` datetime NOT NULL,
`date_modified` datetime NOT NULL,
PRIMARY KEY (`page_id`),
KEY `parent_id` (`parent_id`)
) ENGINE=MyISAM AUTO_INCREMENT=66 DEFAULT CHARSET=utf8;
BEGIN;
INSERT INTO `oc_page` VALUES ('60', '0', '0', '1', '2014-10-16 02:49:41', '2014-10-17 02:03:15'), ('61', '60', '1', '1', '2014-10-17 02:03:02', '2014-10-17 03:17:20'), ('62', '60', '2', '1', '2014-10-17 02:18:59', '2014-10-17 03:16:20'), ('63', '60', '3', '1', '2014-10-17 02:23:27', '2014-10-17 03:16:49'), ('64', '61', '6', '1', '2014-10-17 03:17:49', '2014-10-17 03:17:58'), ('65', '61', '4', '1', '2014-10-17 03:18:36', '2014-10-17 03:18:36');
COMMIT;
DROP TABLE IF EXISTS `oc_page_description`;
CREATE TABLE `oc_page_description` (
`page_id` int(11) NOT NULL,
`language_id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`description` text NOT NULL,
`meta_title` varchar(255) NOT NULL,
`meta_description` varchar(255) NOT NULL,
`meta_keyword` varchar(255) NOT NULL,
PRIMARY KEY (`page_id`,`language_id`),
KEY `name` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
BEGIN;
INSERT INTO `oc_page_description` VALUES ('60', '1', 'Index', '<p>Test</p>', 'Test', '', ''), ('61', '1', 'Sub1', 'Sub1', 'Sub1', '', ''), ('64', '1', 'SubSub1', 'SubSub1', 'SubSub1', '', ''), ('65', '1', 'SubSub2', 'SubSub2', 'SubSub2', '', ''), ('62', '1', 'Sub2', 'Sub2', 'Sub2', '', ''), ('63', '1', 'Sub3', 'Sub3', 'Sub3', '', '');
COMMIT;
DROP TABLE IF EXISTS `oc_page_path`;
CREATE TABLE `oc_page_path` (
`page_id` int(11) NOT NULL,
`path_id` int(11) NOT NULL,
`level` int(11) NOT NULL,
PRIMARY KEY (`page_id`,`path_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
BEGIN;
INSERT INTO `oc_page_path` VALUES ('60', '60', '0'), ('61', '61', '1'), ('61', '60', '0'), ('62', '62', '1'), ('62', '60', '0'), ('63', '63', '1'), ('63', '60', '0'), ('64', '64', '2'), ('64', '60', '0'), ('64', '61', '1'), ('65', '60', '0'), ('65', '61', '1'), ('65', '65', '2');
COMMIT;
DROP TABLE IF EXISTS `oc_page_to_store`;
CREATE TABLE `oc_page_to_store` (
`page_id` int(11) NOT NULL,
`store_id` int(11) NOT NULL,
PRIMARY KEY (`page_id`,`store_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
BEGIN;
INSERT INTO `oc_page_to_store` VALUES ('60', '0'), ('61', '0'), ('62', '0'), ('63', '0'), ('64', '0'), ('65', '0');
COMMIT;
Results :
注意:这是我添加的虚拟数据,以便更多地澄清问题。小提琴将显示更少的数据
SELECT pp.page_id AS page_id,
GROUP_CONCAT(pd1.name
ORDER BY pp.level SEPARATOR ' > ') AS name,
p1.parent_id,
p1.sort_order
FROM oc_page_path pp
LEFT JOIN oc_page p1 ON (pp.page_id = p1.page_id)
LEFT JOIN oc_page p2 ON (pp.path_id = p2.page_id)
LEFT JOIN oc_page_description pd1 ON (pp.path_id = pd1.page_id)
LEFT JOIN oc_page_description pd2 ON (pp.page_id = pd2.page_id)
WHERE pd1.language_id = '1'
AND pd2.language_id = '1'
GROUP BY pp.page_id
ORDER BY name ASC LIMIT 0,20
答案 0 :(得分:1)
您可以简单地使用子查询与内部ORDER
离开显示ORDER
:
SELECT *
FROM (
SELECT pp.page_id AS page_id,
GROUP_CONCAT(pd1.name
ORDER BY pp.level SEPARATOR ' > ') AS name,
p1.parent_id,
p1.sort_order
FROM oc_page_path pp
LEFT JOIN oc_page p1 ON (pp.page_id = p1.page_id)
LEFT JOIN oc_page p2 ON (pp.path_id = p2.page_id)
LEFT JOIN oc_page_description pd1 ON (pp.path_id = pd1.page_id)
LEFT JOIN oc_page_description pd2 ON (pp.page_id = pd2.page_id)
WHERE pd1.language_id = '1'
AND pd2.language_id = '1'
GROUP BY pp.page_id
ORDER BY name ASC LIMIT 0,20
) sub
ORDER BY Sort_Order
演示:SQL Fiddle
注意:由于ORDER BY
,我认为您需要内部LIMIT
,因为如果不是,您只能ORDER BY Sort_Order
。
答案 1 :(得分:0)
如果我理解你的问题你可以砍掉名字的最后一部分,先按顺序排序然后按sort_order排序:
select page_id, parent_id, sort_order, name
, substr(name, 1, length(name) - locate(' > ', reverse(name))) as path
from (
SELECT pp.page_id AS page_id
, GROUP_CONCAT(pd1.name ORDER BY pp.level SEPARATOR ' > ') AS name
, p1.parent_id, p1.sort_order
FROM oc_page_path pp
LEFT JOIN oc_page p1
ON pp.page_id = p1.page_id
LEFT JOIN oc_page p2
ON pp.path_id = p2.page_id
LEFT JOIN oc_page_description pd1
ON pp.path_id = pd1.page_id
LEFT JOIN oc_page_description pd2
ON pp.page_id = pd2.page_id '
WHERE pd1.language_id = '1'
AND pd2.language_id = '1'
GROUP BY pp.page_id, p1.parent_id, p1.sort_order
) as t
order by path, sort_order;
+---------+-----------+------------+----------------------------+-------------------+
| page_id | parent_id | sort_order | name | path |
+---------+-----------+------------+----------------------------+-------------------+
| 60 | 0 | 0 | Index | Index |
| 61 | 60 | 1 | Index > Sub1 | Index > |
| 62 | 60 | 2 | Index > Sub2 | Index > |
| 63 | 60 | 3 | Index > Sub3 | Index > |
| 65 | 61 | 4 | Index > Sub1 > SubSub2 | Index > Sub1 > |
| 64 | 61 | 6 | Index > Sub1 > SubSub1 | Index > Sub1 > |
+---------+-----------+------------+----------------------------+-------------------+