从数据库中选择有序列表

5gfr0r5j  于 2021-06-24  发布在  Mysql
关注(0)|答案(4)|浏览(326)

我收到一张按以下方式订购的table:

NR       | CATNAME
00       | Category 1
00.01    | Subcategory 1
00.01.01 | Subsubcategory 1
00.02    | Subcategory 2
01       | Category 2
01.01    | Subcategory 3
01.02    | Subcategory 4
01.02.01 | Subsubcategory

有没有一种方法可以使用sql轻松地选择特定类别的所有主要类别或子类别(排除此类别的子类别)?问题是,nr列被设置为varchar,因此数学函数可能不是最好的方法。
这不是我的table,我不能改变布局:/

mzaanser

mzaanser1#

对于所有主要类别,都可以使用length()函数。

select *
from   tbl
where  length(NR) = 2;
NR | CATNAME   
:- | :---------
00 | Category 1
01 | Category 2

对于类别的所有组件,可以使用like运算符:

select *
from   tbl
where  NR like '00.01%';
NR       | CATNAME         
:------- | :---------------
00.01    | Subcategory 1   
00.01.01 | Subsubcategory 1

对于类别的所有组件及其子代,可以使用以前查询的组合:

select tbl.*, t1.NR as filter
from   tbl
join   (select NR
        from   tbl
        where  length(NR) = 5) t1
on     tbl.NR like concat(t1.NR, '%');
NR       | CATNAME          | filter
:------- | :--------------- | :-----
00.01    | Subcategory 1    | 00.01 
00.01.01 | Subsubcategory 1 | 00.01 
00.02    | Subcategory 2    | 00.02 
01.01    | Subcategory 3    | 01.01 
01.02    | Subcategory 4    | 01.02 
01.02.01 | Subsubcategory   | 01.02

在这儿摆弄

ndasle7k

ndasle7k2#

如果您使用的是mysql,那么还可以使用正则表达式来过滤类别,这非常方便,并允许创建语义强大的查询(见下文)。
以下示例查询将基于此数据:

create table xxxx1(NR varchar, CATNAME varchar);
insert into xxxx1(NR, CATNAME) values('00', 'Category 1');
insert into xxxx1(NR, CATNAME) values('00.01', 'Subcategory 1');
insert into xxxx1(NR, CATNAME) values('00.01.01', 'Subsubcategory 1');
insert into xxxx1(NR, CATNAME) values('00.02', 'Subcategory 2');
insert into xxxx1(NR, CATNAME) values('01', 'Category 2');
insert into xxxx1(NR, CATNAME) values('01.01', 'Subcategory 3');

示例:
类别2的所有子类别:

select * from xxxx1 where NR REGEXP '^01.+';
+-------+---------------+
| NR    | CATNAME       |
+-------+---------------+
| 01.01 | Subcategory 3 |
+-------+---------------+

类别1的所有子类别:

select * from xxxx1 where NR REGEXP '^00.+';
+----------+------------------+
| NR       | CATNAME          |
+----------+------------------+
| 00.01    | Subcategory 1    |
| 00.01.01 | Subsubcategory 1 |
| 00.02    | Subcategory 2    |
+----------+------------------+

所有顶级类别:

select * from xxxx1 where NR REGEXP '^[0-9][0-9]$';
+------+------------+
| NR   | CATNAME    |
+------+------------+
| 00   | Category 1 |
| 01   | Category 2 |
+------+------------+

第二级的所有子类别:

mysql> select * from xxxx1 where NR REGEXP '^[0-9][0-9].[0-9][0-9]$';
+-------+---------------+
| NR    | CATNAME       |
+-------+---------------+
| 00.01 | Subcategory 1 |
| 00.02 | Subcategory 2 |
| 01.01 | Subcategory 3 |
+-------+---------------+

第三级的所有子类别:

mysql> select * from xxxx1 where NR REGEXP '^([0-9][0-9]\.?){3}$';
+----------+------------------+
| NR       | CATNAME          |
+----------+------------------+
| 00.01.01 | Subsubcategory 1 |
+----------+------------------+
b0zn9rqh

b0zn9rqh3#

类别+子类别:
从ct2.parent\u id=ct1.id的categories\u table ct1 left join categories\u table ct2中选择ct1.id、ct1.name、ct2.id、ct2.name,其中ct1.parent\u id=catnameorid
类别+子类别+子类别:
从ct2.parent\u id=ct1.id left join categories\u table ct1 left join categories\u table ct2 on ct2.parent\u id=ct1.id left join categories\u table ct3 on ct3.parent\u id=ct2.id中选择ct1.id、ct1.name、ct2.id、ct2.name、ct3.id、ct3.name,其中ct1.parent\u id=catnameorid

lskq00tm

lskq00tm4#

据我所知,你描述的任务,这是关于树中的级别。你可以通过数点得到:

-- All main categories:
select *
from mytable
where length(nr) - length(replace(nr,'.','')) = 0
order by nr;
NR       | CATNAME
---------+--------------
00       | Category 1
01       | Category 2
-- All direct subcategories of category '01':
select *
from mytable
where nr like '01%'
and length(nr) - length(replace(nr,'.','')) = 1
order by nr;
NR       | CATNAME
---------+--------------
01.01    | Subcategory 3
01.02    | Subcategory 4

rextester演示:http://rextester.com/dkqyk10570

相关问题