我有三个表,我需要一个查询来正确返回结果。
第一个表是包含父类别和子类别的类别表。该表允许所有级别的子表,包括子类别的子表。
第二个表是一个可以属于类别的文件表。这与类别表有很多关系。这些文件也可以属于包含子类别的类别。
第三个表创建了文件和类别之间的多对多关系。
第一个表格是Categories
:
CREATE TABLE Categories (
category_id INT NOT NULL PRIMARY KEY,
category_name varchar(20) NOT NULL,
parent_id INT NOT NULL
);
第二个表格是Files
CREATE TABLE Files (
file_id INT NOT NULL PRIMARY KEY,
file_name varchar(20) NOT NULL
);
第三个表将文件链接到类别。文件可以属于任何类别,可以属于多个类别
CREATE TABLE Category_File (
category_id INT NOT NULL,
file_id INT NOT NULL
);
表格填写如下:
INSERT INTO Categories (category_id, category_name, parent_id) VALUES
(1, 'Cat1', 0),(2, 'Cat2', 0),(3, 'Cat3', 1),
(4, 'Cat4', 2),(5, 'Cat5', 1),(6, 'Cat6', 0),
(7, 'Cat7', 5),(8, 'Cat8', 4),(9, 'Cat9', 7);
INSERT INTO Files (file_id, file_name) VALUES
(1, 'File1'),(2, 'File2'),(3, 'File3'),
(4, 'File4'),(5, 'File5'),(6, 'File6');
INSERT INTO Category_File (category_id, file_id) VALUES
(3, 1),(4, 2),(5, 3),
(9, 6),(7, 2),(5, 4),
(8, 4),(6, 1),(3, 5);
我需要返回以显示按名称排序的类别,然后显示按名称排序的文件。因此,查询包含所有列的所有记录将导致
Result Set 1
[
category_id, category_name, file_id, file_name parent_id
1 Cat1 Null Null 0
3 Cat3 Null Null 1
3 Cat3 1 File1 Null
3 Cat3 5 File5 Null
5 Cat5 Null Null 1
5 Cat5 3 File3 Null
5 Cat5 4 File4 Null
7 Cat7 Null Null 5
7 Cat7 2 File2 Null
9 Cat9 Null Null 7
9 Cat9 6 File6 Null
2 Cat2 Null Null 0
4 Cat4 Null Null 2
4 Cat4 2 File2 Null
8 Cat8 Null Null 4
8 Cat8 4 File4 Null
6 Cat6 Null Null 0
6 Cat6 1 File1 Null
]
答案 0 :(得分:1)
declare @Categories table(
category_id INT NOT NULL PRIMARY KEY,
name varchar(20) NOT NULL,
parent_id INT NOT NULL
);
declare @Files table(
file_id INT NOT NULL PRIMARY KEY,
name varchar(20) NOT NULL
);
declare @Category_File table(
category_id INT NOT NULL,
file_id INT NOT NULL
);
INSERT INTO @Categories (category_id, name, parent_id) VALUES
(1, 'Cat1', 0),
(2, 'Cat2', 0),
(3, 'Cat3', 1),
(4, 'Cat4', 2),
(5, 'Cat5', 1),
(6, 'Cat6', 0),
(7, 'Cat7', 5),
(8, 'Cat8', 4),
(9, 'Cat9', 7);
INSERT INTO @Files (file_id, name) VALUES
(1, 'File1'),
(2, 'File2'),
(3, 'File3'),
(4, 'File4'),
(5, 'File5'),
(6, 'File6');
INSERT INTO @Category_File (category_id, file_id) VALUES
(3, 1),
(4, 2),
(5, 3),
(9, 6),
(7, 2),
(5, 4),
(8, 4),
(6, 1),
(3, 5);
;with cteC as
(
select c.category_id, c.name as category_name, cast(null as int) as file_id, cast(null as varchar(max)) as file_name, c.parent_id
from @Categories c
where parent_id = 0
union all
select category_id,name,file_id,file_name,parent_id
from
(
select ch.category_id, ch.name, null file_id , null file_name, ch.parent_id
from cteC c
join @Categories ch on ch.parent_id = c.category_id
)sq
)
select c.category_id, c.category_name, cast(null as int) as file_id, cast(null as varchar(max)) as file_name, c.parent_id
from cteC c
union all
select c.category_id, c.category_name, f.file_id, cast(f.name as varchar(max)), cast(null as int)
from cteC c
join @Category_File cf on cf.category_id = c.category_id
and c.file_id is null
join @Files f on f.file_id = cf.file_id
order by category_name, file_name
答案 1 :(得分:0)
此查询应该有效。它建立在@Oleg给出的答案之上,但有一些简化,并添加了一个级别属性以确保正确的排序。
我把它变成了一个社区维基,因为我不想为别人的工作赢得赞誉......
;with cte as
(
select c.category_id, c.category_name, c.parent_id, cast(category_id as varchar(max)) as lvl
from categories c where parent_id = 0
union all
select ch.category_id, ch.category_name, ch.parent_id, c.lvl + ',' + cast(ch.category_id as varchar(max)) as lvl
from cte c join categories ch on ch.parent_id = c.category_id
)
select category_id, category_name, file_id, file_name, parent_id
from (
select c.category_id, c.category_name, null as file_id, null as file_name, c.parent_id, lvl
from cte c
union all
select c.category_id, c.category_name, f.file_id, f.file_name, null, lvl
from cte c
join category_file cf on cf.category_id = c.category_id
join files f on f.file_id = cf.file_id
) a
order by lvl, category_name, file_name