我有一个'类别'表。每行都有一个'CategoryId'(必需)和一个'ParentCategoryId'(不是必需的)。这允许父类 - >类别之间的子关系。
我要做的是选择所有类别,但如果存在父 - >子关系,则只选择父级。
这就是我目前正在尝试的东西,但这是永远的,并且只是错误的。免责声明,SQL不是我的强项!
declare @ProjectId int
set @ProjectId = 1
declare @catid int
declare @catname nvarchar(100)
declare @catprojid int
declare @catparentid int
declare @sortorder int
declare db_cursor cursor for
select categoryid,categoryname,projectid,parentcategoryid,sortorder from dbo.ProjectCategories
where ProjectId = @ProjectId
open db_cursor
fetch NEXT from db_cursor into @catid,@catname,@catprojid,@catparentid,@sortorder
while @@FETCH_STATUS = 0
begin
if @catparentid != null select * from dbo.ProjectCategories where CategoryId = @catparentid
else select @catid,@catname,@catprojid,@catparentid,@sortorder
end
close db_cursor
deallocate db_cursor
go
答案 0 :(得分:2)
以下选择检索至少一个其他类别的父项的所有类别:
declare @ProjectId int
set @ProjectId = 1
select distinct
parent.categoryid,
parent.categoryname,
parent.projectid,
parent.parentcategoryid,
parent.sortorder
from dbo.ProjectCategories parent
join dbo.ProjectCategories child on child.ParentCategoryId = parent.CategoryId
where parent.ProjectId = @ProjectId
答案 1 :(得分:0)
应该相当简单:
select categoryid,categoryname,projectid,parentcategoryid,sortorder
from dbo.ProjectCategories
where parentcategoryid is null
答案 2 :(得分:0)
SELECT
COALESCE(parent.categoryid, child.categoryid),
COALESCE(parent.categoryname, child.categoryname),
COALESCE(parent.projectid, child.projectid),
COALESCE(parent.parentcategoryid, child.parentcategoryid),
COALESCE(parent.sortorder, child.sortorder)
FROM
dbo.ProjectCategories child
LEFT JOIN dbo.ProjectCategories parent
ON child.parentcategoryid = parent.categoryid
WHERE
child.ProjectId = @ProjectId
COALESCE返回第一个非NULL参数。
一个更安全的版本,在父类别的某些列为NULL的情况下
SELECT
CASE WHEN parent.categoryid IS NULL THEN child.categoryid ELSE parent.categoryid END,
CASE WHEN parent.categoryid IS NULL THEN child.categoryname ELSE parent.categoryname END,
CASE WHEN parent.categoryid IS NULL THEN child.projectid ELSE parent.projectid END,
CASE WHEN parent.categoryid IS NULL THEN child.parentcategoryid ELSE parent.parentcategoryid END,
CASE WHEN parent.categoryid IS NULL THEN child.sortorder ELSE parent.sortorder END
FROM
dbo.ProjectCategories child
LEFT JOIN dbo.ProjectCategories parent
ON child.parentcategoryid = parent.categoryid
WHERE
child.ProjectId = @ProjectId
答案 3 :(得分:0)
这将列出所有有孩子的父母。不会显示没有孩子的父母。
DECLARE @ProjectCategories TABLE
(
categoryid INT,
categoryname VARCHAR(10),
projectid INT,
parentcategoryid INT,
sortorder INT
)
INSERT INTO @ProjectCategories
SELECT 1, 'Main1', 1, null, 1 UNION ALL
SELECT 2, 'Child1', 1, 1, 1 UNION ALL
SELECT 3, 'Child2', 1, 2, 1 UNION ALL
SELECT 4, 'Child3', 1, 3, 1 UNION ALL
SELECT 5, 'Child4', 1, 4, 1 UNION ALL
SELECT 6, 'MainA', 2, null, 1 UNION ALL
SELECT 7, 'ChildA', 2, 6, 1 UNION ALL
SELECT 8, 'ChildB', 2, 7, 1 UNION ALL
SELECT 9, 'Main!', 3, null, 1
SELECT *
FROM @ProjectCategories Child
INNER JOIN @ProjectCategories Parent
ON Child.parentcategoryid = Parent.categoryid
AND Parent.parentcategoryid IS NULL
以下是所有父母,无论是否有孩子:
DECLARE @ProjectCategories TABLE
(
categoryid INT,
categoryname VARCHAR(10),
projectid INT,
parentcategoryid INT,
sortorder INT
)
INSERT INTO @ProjectCategories
SELECT 1, 'Main1', 1, null, 1 UNION ALL
SELECT 2, 'Child1', 1, 1, 1 UNION ALL
SELECT 3, 'Child2', 1, 2, 1 UNION ALL
SELECT 4, 'Child3', 1, 3, 1 UNION ALL
SELECT 5, 'Child4', 1, 4, 1 UNION ALL
SELECT 6, 'MainA', 2, null, 1 UNION ALL
SELECT 7, 'ChildA', 2, 6, 1 UNION ALL
SELECT 8, 'ChildB', 2, 7, 1 UNION ALL
SELECT 9, 'Main!', 3, null, 1
SELECT *
FROM @ProjectCategories Parent
WHERE Parent.parentcategoryid IS NULL
这是一个递归的CTE,无论有多少孩子,它都会为父母提供所有孩子。
DECLARE @ProjectCategories TABLE
(
categoryid INT,
categoryname VARCHAR(10),
projectid INT,
parentcategoryid INT,
sortorder INT
)
INSERT INTO @ProjectCategories
SELECT 1, 'Main1', 1, null, 1 UNION ALL
SELECT 2, 'Child1', 1, 1, 1 UNION ALL
SELECT 3, 'Child2', 1, 2, 1 UNION ALL
SELECT 4, 'Child3', 1, 3, 1 UNION ALL
SELECT 5, 'Child4', 1, 4, 1 UNION ALL
SELECT 6, 'MainA', 2, null, 1 UNION ALL
SELECT 7, 'ChildA', 2, 6, 1 UNION ALL
SELECT 8, 'ChildB', 2, 7, 1 UNION ALL
SELECT 9, 'Main!', 3, null, 1
;WITH Projects
(
categoryid,
categoryname,
parentcategoryid
)
AS
(
-- Base Case
SELECT categoryid,
categoryname,
parentcategoryid
FROM @ProjectCategories
WHERE projectid = 1 -- Change this to 1, 2, or 3
AND parentcategoryid IS NULL
UNION ALL
-- Recursive
SELECT pc.categoryid,
pc.categoryname,
pc.parentcategoryid
from Projects
INNER JOIN @ProjectCategories pc
ON pc.parentcategoryid = Projects.categoryid
)
SELECT * from Projects