从数据库中选择有序列表

时间:2018-04-10 09:11:46

标签: mysql sql select

我收到了以下列方式订购的桌子:

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-Column被设置为VARCHAR,因此Math-Functions可能不是最好的主意。

它不是我的桌子,我无法更改布局:/

4 个答案:

答案 0 :(得分:1)

据我了解您描述的任务,这是关于树中的级别。你可以通过数点来计算:

-- 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
---------+--------------
00       | Category 1
01       | Category 2
::after
NR       | CATNAME
---------+--------------
01.01    | Subcategory 3
01.02    | Subcategory 4

Rextester演示:http://rextester.com/DKQYK10570

答案 1 :(得分:1)

对于所有主要类别,您可以使用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 

dbfiddle here

答案 2 :(得分:1)

如果您使用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 |
+----------+------------------+

答案 3 :(得分:0)

类别+子类别:
SELECT ct1.id,ct1.name,ct2.id,ct2.name FROM categories_table ct1   LEFT JOIN categories_table ct2     ON ct2.parent_id = ct1.id 在哪里ct1.parent_id = CATNAMEORID

类别+子类别+子子类别:
SELECT ct1.id,ct1.name,ct2.id,ct2.name,ct3.id,ct3.name FROM categories_table ct1   LEFT JOIN categories_table ct2     ON ct2.parent_id = ct1.id   LEFT JOIN categories_table ct3     ON ct3.parent_id = ct2.id WHERE ct1.parent_id = CATNAMEORID