条件SQL Select语句

时间:2012-01-16 20:38:20

标签: .net sql sql-server sql-server-2008 tsql

我有一个'类别'表。每行都有一个'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

4 个答案:

答案 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