Mysql 按顺序显示类别和子类别
在创建一个SQL查询来显示一个表中的类别和子类别时,我遇到了很多麻烦。我有以下专栏:Mysql 按顺序显示类别和子类别,mysql,sql,Mysql,Sql,在创建一个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_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
如果类别顺序设置为0,则应根据类别或子类别的创建顺序对其进行排序。为此,我计划按id排序
如果可能的话,我想使用一个联合,这样他们就已经有序了,我只需要循环。有人能帮我建立一个查询吗
实际上我已经有一个使用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
但是,它不会对子类别进行排序,因为父类别和子类别是合并的。我的查询仅对父级进行排序。当树的深度仅限于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\u parent为NULL
来测试类别的级别。我认为排序是这里有趣的部分。特别是,类别内的排序是有趣的。我做了一把小提琴来说明这一点:
问题是:
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
进行排序。我遇到了相同的问题,并测试了许多示例或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
我在测试解决方案后编写了这个解决方案,其中排序是通过创建一个串联字符串来完成的,由三个字符串组成:第一个字符串用于父类别的主排序顺序,第二个字符串用于对父类别及其子类别进行分组,第三个字符串用于根据子类别排序对父类别及其子类别进行排序(为了将父cat放在第一位,他们被赋予了一个虚拟的子cat排序顺序设置为0)。但是这个字符串排序,给出了字母顺序,而不是数字顺序。因此,将排序字符串转换为额外的数字字段,就像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
- 第一种情况是检测类别是否为父类别。如果是父类别,则保留父类别的排序顺序,如果是子类别,则将其排序顺序替换为父类别的排序顺序
- 第二种情况是,用父类别id替换子类别id(这相当于JTseng groupid)
- 第三种情况用于将0设置为父子排序顺序并保持子cat排序顺序
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
我找到了一个简单的方法,它是按等级和字母顺序排列的 首先,我放置了查看示例所需的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;
现在可以快速插入结果:
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
插入类别
(类别id
,类别父项
,类别名称
)值
(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类的第一个子类”),
(11,1,'类别编号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
选择类别标识、类别父项、类别名称、,
(案例
当category\u parent=category\u id或category\u parent=0时,则category\u id
当类别\u父类别\u id时,则为类别\u父类别
结束)作为“家长”
根据父ASC、类别父ASC、类别名称ASC的类别顺序
我希望它有用这是我对三个子类别级别1、级别2和级别3的深度回答
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
您的查询看起来与此类似(从示意图上讲)
希望有帮助
select *, if (parent_category_id is NULL, id, concat(parent_category_id, id)) as o
from category
order by o
你能发布你的加入查询吗?有什么问题吗?树的深度是否像你的例子中那样被限制为2?树的深度是否被限制?只有父类和子类。没有子类,我的问题是它没有对子类进行排序,而且每个子类也有父类的详细信息。i我不想要我不需要的额外列我喜欢你的答案。如果我没有得到这个错误,我会使用它的####正确的语法使用near'c as(选择c.*,coalesce(c.parent,c.id)作为groupID,c.par'在第行时的情况1@user949000抱歉。我没有看到数据库版本。我会用mysql修复这个问题,并让您知道。@user949000我已经编辑了我的答案以使用mysql。这个问题也被更新了。@user949000错误的部分是,当没有父项时,我假设父项为空,但您的数据的父项为0。A另外,我没有假设子类别会有一个订单。我已经更新了查询和小提琴。我会让你自己修复其余的。祝你好运。