Mysql 按顺序显示类别和子类别

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

在创建一个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
如果类别顺序设置为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排序顺序
要查看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

我找到了一个简单的方法,它是按等级和字母顺序排列的

首先,我放置了查看示例所需的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另外,我没有假设子类别会有一个订单。我已经更新了查询和小提琴。我会让你自己修复其余的。祝你好运。