csjoz11

导航

MySQL根据父ID排序类别

mysql sort category according to parent id

https://mp.baomidou.com/guide/wrapper.html#nested

LamdaQueryWrapper<Member> MemberWrapper = new LamdaQueryWrapper<Member>();
MemberWrapper.last( " CONVERT(name USING GBK) ASC")
Member.instance().selectOne(MemberWrapper )

apply


 
apply(String applySql, Object... params)
apply(boolean condition, String applySql, Object... params)
  • 拼接 sql

    注意事项:

    该方法可用于数据库函数 动态入参的params对应前面applySql内部的{index}部分.这样是不会有sql注入风险的,反之会有!

  • 例: apply("id = 1")--->id = 1
  • 例: apply("date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")--->date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")
  • 例: apply("date_format(dateColumn,'%Y-%m-%d') = {0}", "2008-08-08")--->date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")

#last


 
last(String lastSql)
last(boolean condition, String lastSql)
  • 无视优化规则直接拼接到 sql 的最后

    注意事项:

    只能调用一次,多次调用以最后一次为准 有sql注入的风险,请谨慎使用

  • 例: last("limit 1")

#exists


 
exists(String existsSql)
exists(boolean condition, String existsSql)
  • 拼接 EXISTS ( sql语句 )
  • 例: exists("select id from table where age = 1")--->exists (select id from table where age = 1)

#notExists

select name,CASE WHEN parent_id= 0 THEN id ELSE parent_id END Sort from member ORDER BY sort,id
select name from member order by case when parent_id=0 then id else parent_id END,parent_id,id
 
    @Autowired
    private MemberMapper memberMapper;
    @Test
    void test1() {
        QueryWrapper<Member> wrapper = new QueryWrapper<>();

        wrapper.last("order by case when parent_id=0 then id else parent_id END,parent_id,id");
//        wrapper.addFilter
        List<Member> members = memberMapper.selectList(wrapper);


        members.forEach(System.out::println);


    }
问 题
 

这是表结构

id   parent_id   name
1    0           BMW
2    0           Mercedez
3    0           Porsche
4    1           3 Series
5    2           E60
6    1           5 Series
7    3           Cayenne

如何将表格显示为

BMW
3 Series
5 Series
Mercedez
E60
Porsche
Cayenne 

上表显示升序I​​D,后跟与该ID相关联的parent_id,然后转到第二个ID,依此类推.我需要在单个查询中,是否可以这样做?

解决方案

尝试一下:

SELECT
  name,
  CASE WHEN parent_id = 0 THEN id ELSE parent_id END AS Sort
FROM
  cars
ORDER BY
  Sort,
  id

http://sqlfiddle.com/#!2/9b05f/3


编辑:

鉴于此答案一直在增加,我重新考虑了这个问题并发现了一个缺陷.如果由于某种原因,父级的ID高于子级的ID,则排序会混乱.仅当父ID的编号小于所有子ID的编号时,以上查询才有效.

为演示该问题,请想象表看起来像这样:

id   parent_id   name
8    0           BMW
2    0           Mercedez
3    0           Porsche
4    8           3 Series
5    2           E60
6    8           5 Series
7    3           Cayenne

现在请注意,BMW的id为 8 ,而不是 1 .结果将如下所示:

Mercedez
E60
Porsche
Cayenne
3 Series
5 Series
BMW

请注意, BMW 显示在列表的底部,之后其子项!这是因为id的二级排序顺序,并且如果父ID碰巧高于任何子代,则父代可能不会出现在子代之上.

此查询将解决该问题:

SELECT
  name
FROM
  cars
ORDER BY
  CASE WHEN parent_id = 0 THEN id ELSE parent_id END, -- another way of writing it: ISNULL(NULLIF(parent_id, 0), id)
  parent_id,
  id

http://sqlfiddle.com/#!2/6d6d73/3

要解释这里发生的情况,请先按父行的id字段和子行的parent_id字段排序.如果按此顺序进行排序,则所有子项都将与其父项归为一组,并且整个列表将由父项的id字段进行排序.

但是,这并没有设置家庭内部的排序,因此父母可以出现在家庭内部的任何位置(父母可以出现在顶部,或者可以出现在中间,或者可以是最后).

这是其他两个排序字段的输入位置.第二个字段按parent_id排序,父行的parent_id字段始终为0.安全地假设您的ID字段始终为正,这意味着父记录将始终显示在家族的顶部.其余子项的parent_id值均相同,因此第三个排序字段通过id字段对家庭中的子项进行排序.也可以将其更改为name,具体取决于您希望孩子如何排序.

posted on 2021-09-23 23:15  csjoz11  阅读(396)  评论(0编辑  收藏  举报