您希望获得父 ID:
所以假设你得到
set @parentId = 1 /*toys*/
select
*
from
Items i
inner join Categories c on c.id = i.categoryId
where
c.parentId = @parentId
这将为您提供您想要的项目 - 一个主要的设计缺陷:它不处理多个层次的层次类别。
假设您有这个类别表:
*Categories table*
id | name | parentId
1 | Toys | 0
2 | Dolls | 1
3 | Bikes | 1
4 | Models | 2
5 | Act.Fig.| 2
6 | Mountain| 3
7 | BMX | 3
和项目:
*items table*
item | category_id
Barbie | 4
GIJoe | 5
Schwinn| 6
Huffy | 7
获取所有相关项目的唯一方法是进行自我加入:
select
*
from
Items i
inner join Categories c on c.id = i.categoryId
inner join Categories c2 on c.parentId = c2.id
where
c2.parentId = @parentId
这种模式是不可扩展的——因为你可以有多个层次的层次。
处理层次结构的一种常见方法是构建一个“扁平化”表:将每个节点链接到它的所有后代的行。
除了 Categories 表之外,您还构建了第二个表:
*CategoriesFlat table* The Name column is here only for readability
id | name | parentId
1 | Toys | 1
-----------------
2 | Dolls | 1
2 | Dolls | 2
-----------------
4 | Models | 1
4 | Models | 2
4 | Models | 4
5 | Act.Fig.| 1
5 | Act.Fig.| 2
5 | Act.Fig.| 5
-----------------
3 | Bikes | 1
3 | Bikes | 3
-----------------
6 | Mountain| 1
6 | Mountain| 3
6 | Mountain| 6
7 | BMX | 1
7 | BMX | 3
7 | BMX | 7
所以你可以写:
select
*
from
Items i
inner join CategoriesFlat c on c.id = i.categoryId
where
c.parentId = @parentId
并获取所有相关的类别和项目。
这是关于 SQL 反模式及其解决方案的精彩幻灯片。(SQL 中的分层数据是一种反模式,但不要灰心——我们都会遇到这种情况)