在创建SQL查询以显示一个表中的类别和子类别时,我遇到了很多麻烦。我有以下专栏:
category_id
category_name
category_parent
category_order
基本上我想要产生的结果是这样的
parent category 1
sub category 1
sub category 2
parent category 2
sub category 1
sub category 2
sub category 3
parent category 3
sub category 1
如果category_order设置为0,则应根据创建的顺序对类别或子类别进行排序。为此我打算按ID排序。
如果可能的话我想使用UNION,以便它们已经按顺序排列,我只需要循环。任何人都可以帮我建立一个查询。
实际上我已经有一个使用JOIN,但结果并不像我想要的那样精确。
这是我之前的查询:
SELECT
fcat.id fcat_id,
fcat.name fcat_name,
fcat.order fcat_order,
fcat.parent fcat_parent,
fsub.id fsub_id,
fsub.name fsub_name,
fsub.order fsub_order,
fsub.parent fsub_parent
FROM forum_categories AS fcat
LEFT OUTER JOIN forum_categories AS fsub ON fcat.id = fsub.parent
ORDER BY ISNULL(fcat.order) ASC, fcat.id ASC, ISNULL(fsub.order) ASC, fsub.id ASC
但是,它不对子类别进行排序,因为父类别和子类别已连接。我的查询只对父母进行排序。
答案 0 :(得分:4)
我认为排序是这里有趣的部分。特别是,类别中的排序很有趣。我做了一个小提琴,说明了这一点:http://sqlfiddle.com/#!8/78059/3
以下是查询:
select * from (
select c.*,
coalesce(nullif(c.parent, 0), c.id) as groupID,
case when c.parent = 0 then 1 else 0 end as isparent,
case when p.`order` = 0 then c.id end as orderbyint
from category c
left join category p on p.id = c.parent
) c order by groupID, isparent desc, orderbyint, name
我们可以使用是否为父类来注释每个类别。然后我们可以对类别进行分组。在每个组中,订单取决于父订单。在parent.order
为0时,我正在根据id执行一个订单。如果它不是0,那么orderbyint
为空,然后我们将按name
排序。
答案 1 :(得分:2)
当树的深度仅限于2时:
select c1.*,
c2.*,
if (c2.category_parent is NULL, "parent category", "sub category") as text
from cat c1 left join cat c2
on c1.category_id = c2.category_parent
order by c1.category_id, c2.category_id
您可以使用条件c2.category_parent is NULL
来测试类别的级别。
答案 2 :(得分:0)
我遇到了同样的问题并测试了许多示例或Tomas和JTseng解决方案。这些都缺少数字排序或子类别排序。我修改了JTseng查询,现在就可以了(对我而言),这样:
SELECT c.*,
CASE WHEN isnull(is_par.cat_id) THEN c.cat_sort_order ELSE is_par.cat_sort_order END as sort_order,
CASE WHEN isnull(is_par.cat_id) THEN c.cat_id ELSE is_par.cat_id END as catid ,
CASE WHEN isnull(is_par.cat_id) THEN 0 ELSE c.cat_sort_order END as subcat_order
FROM `category` c
LEFT JOIN `category` is_par ON is_par.cat_id = c.cat_parent_id
ORDER BY sort_order , catid, subcat_order
我在测试解决方案之后编写了这个解决方案,其中通过创建由三个字符串组成的连接字符串进行排序:第一个用于父类别的主要排序顺序,第二个用于分组父类别及其子类,第三个根据子命令对父母及其子女进行排序的字符串(并将父母猫放在第一位,给他们一个虚拟子猫排序顺序设置为0)。但是这个字符串排序给出了字母排序,而不是数字排序。因此,将JTseng转换为额外数字字段的转换顺序如下:
要查看LEFT JOIN操作,只需在phpMyAdmin页面中执行此查询:
SELECT c.cat_id as ccatid,c.cat_sort_order as ccatsortorder, is_par.cat_id as isparcatid,is_par.cat_parent_id as ispar_catparentid,is_par.cat_sort_order as isparcatsortorder,
CASE WHEN isnull(is_par.cat_id) THEN c.cat_sort_order ELSE is_par.cat_sort_order END as sort_order,
CASE WHEN isnull(is_par.cat_id) THEN c.cat_id ELSE is_par.cat_id END as catid,
CASE WHEN isnull(is_par.cat_id) THEN 0 ELSE c.cat_sort_order END as subcat_order
FROM `category` c
LEFT JOIN `category` is_par ON is_par.cat_id = c.cat_parent_id
答案 3 :(得分:0)
我找到了一种简单的方法。它按层次结构和字母顺序排列。
首先,我把SQL需要看看例子:
CREATE TABLE IF NOT EXISTS `categories` (
`category_id` int(11) NOT NULL AUTO_INCREMENT,
`category_parent` int(11) NOT NULL,
`category_name` varchar(100) COLLATE latin1_spanish_ci NOT NULL,
PRIMARY KEY (`category_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci;
现在快速插入以获得结果:
INSERT INTO categories
(category_id
,category_parent
,category_name
)价值观
(1,0,'类别编号1'),
(2,0,'类别编号2'),
(3,0,'类别编号3'),
(4,0,'类别编号4'),
(5,0,'类别编号5'),
(6,0,'类别编号6'),
(7,2,'类别2'的第一个子类别),
(8,2'类别2'的第二子类别),
(9,2,'和类别2的第三个子类别(必须首先出现,因为字母顺序)'),
(10,1,'类别编号1和#39;的第一个子类别),
(11,1,' Ans类别编号1的第二个子类别(必须首先出现,因为按字母顺序排列)');
和SQL句子:
SELECT category_id,category_parent,category_name,
(CASE
WHEN category_parent=category_id OR category_parent=0 THEN category_id
WHEN category_parent<>category_id THEN category_parent
END) AS 'the_parent'
FROM categories ORDER BY the_parent ASC, category_parent ASC, category_name ASC
我希望它有用
答案 4 :(得分:0)
这是我对3个子类别level1,level2和level3
深度的回答SELECT
main.id AS main_id,
level1.id AS level1_id,
level2.id AS level2_id,
level3.id AS level3_id
FROM
categories AS main
LEFT OUTER JOIN categories AS level1 ON level1.parent_id = main.id
LEFT OUTER JOIN categories AS level2 ON level2.parent_id = level1.id
LEFT OUTER JOIN categories AS level3 ON level3.parent_id = level2.id
WHERE
main.parent_id = "ID-OF-MAIN-CATEGORY"
ORDER BY
main_id,
level1_id,
level2_id,
level3_id
您的查询看起来与此类似(示意性地说)
希望有所帮助
答案 5 :(得分:0)