在SQL中,如何通过列值获取与父级相关的值

在SQL中,如何通过列值获取与父级相关的值,sql,sql-server,sql-server-2005,sql-server-2000,Sql,Sql Server,Sql Server 2005,Sql Server 2000,我在SQLServer2005和最低版本上工作 我有一个SQL Server表结构,如下所示: ID Name ParentID ----------------------- 1 Root NULL 2 Business 1 3 Finance 1 4 Stock 3 我想写一个查询,当用户输入ID=1时,在这里显示这个输出: ID Name ParentName ------------------

我在SQLServer2005和最低版本上工作

我有一个SQL Server表结构,如下所示:

ID    Name     ParentID
-----------------------
1     Root       NULL
2     Business   1
3     Finance    1
4     Stock      3
我想写一个查询,当用户输入ID=1时,在这里显示这个输出:

ID    Name     ParentName
-------------------------
1     Root      -
2     Business  Root
3     Finance   Root
4     Stock     Finance    
ID    Name     ParentName
-------------------------
3     Finance   Root
1     Root      -
4     Stock     Finance 
当用户给出输入ID=3时,在此处显示此输出:

ID    Name     ParentName
-------------------------
1     Root      -
2     Business  Root
3     Finance   Root
4     Stock     Finance    
ID    Name     ParentName
-------------------------
3     Finance   Root
1     Root      -
4     Stock     Finance 
当用户输入ID=4时,则显示此输出:

ID    Name     ParentName
-------------------------
4     Stock     Finance    
3     Finance   Root
1     Root      -
ID  Name    ParentID
 1  Root      NULL
 2  Business  1
 3  Finance   1
 4  Stock     3
ID  Name     ParentID
 1  Root     NULL
 3  Finance   1
 4  Stock     3
提前谢谢。如果有任何疑问,请询问。谢谢大家

SELECT t1.ID, t1.Name, t2.Name AS ParentName FROM tableName t1
LEFT JOIN tableName t2 on t1.ID = t2.ParentID
用表替换tableName。
如果愿意,添加t2.ID以选择要查看匹配的列表。

这两个递归CTE的公共表表达式将从树中的给定节点以及从树上的该节点返回到根节点来选择层次结构。由于它是一个CTE,它将在SQLServer2005和更新的版本中工作,但不幸的是,在SQLServer2000中不能工作

DECLARE @StartID INT 
SET @StartID = 1

;WITH DownHierarchy AS
(
    SELECT ID, Name, ParentID
    FROM dbo.YourTable
    WHERE ID = @StartID

    UNION ALL

    SELECT d.ID, d.Name, d.ParentID
    FROM dbo.YourTable d
    INNER JOIN DownHierarchy h ON d.ParentID = h.ID
),
UpHierarchy AS
(
    SELECT ID, Name, ParentID
    FROM dbo.YourTable
    WHERE ID = @StartID

    UNION ALL

    SELECT d.ID, d.Name, d.ParentID
    FROM dbo.YourTable d
    INNER JOIN UpHierarchy h ON d.ID = h.ParentID
)
SELECT *
FROM DownHierarchy
UNION 
SELECT *
FROM UpHierarchy
设置@StartID=1将为您提供以下输出:

ID    Name     ParentName
-------------------------
4     Stock     Finance    
3     Finance   Root
1     Root      -
ID  Name    ParentID
 1  Root      NULL
 2  Business  1
 3  Finance   1
 4  Stock     3
ID  Name     ParentID
 1  Root     NULL
 3  Finance   1
 4  Stock     3
设置@StartID=3将为您提供以下输出:

ID    Name     ParentName
-------------------------
4     Stock     Finance    
3     Finance   Root
1     Root      -
ID  Name    ParentID
 1  Root      NULL
 2  Business  1
 3  Finance   1
 4  Stock     3
ID  Name     ParentID
 1  Root     NULL
 3  Finance   1
 4  Stock     3

下面是对marc_答案的修改:

  Declare @data table
(ID bigint identity(1,1)   ,Name varchar(100),    ParentID bigint)

Insert into @data SELECT 'Root',NULL
Insert into @data SELECT 'Business',1
Insert into @data SELECT 'Finance',1
Insert into @data SELECT 'Stock',3


DECLARE @StartID INT 
SET @StartID = 3

;WITH DownHierarchy AS
(
    SELECT ID, Name, ParentID
    FROM @data
    WHERE ID = @StartID

    UNION ALL

    SELECT d.ID, d.Name, d.ParentID
    FROM @data d
    INNER JOIN DownHierarchy h ON d.ParentID = h.ID
),
UpHierarchy AS
(
    SELECT ID, Name, ParentID
    FROM @data
    WHERE ID = @StartID

    UNION ALL

    SELECT d.ID, d.Name, d.ParentID
    FROM @data d
    INNER JOIN UpHierarchy h ON d.ID = h.ParentID
)
SELECT *
FROM DownHierarchy
UNION 
SELECT *
FROM UpHierarchy

我有一个类似的答案——但在构建了它之后,我想发布它

declare @Data table (
    ID int not null,
    Name varchar(50) not null,
    ParentID int null
);

insert into @Data
select  1, 'Root', null
union select 2, 'Business', 1
union select 3, 'Finance', 1
union select 4, 'Stock', 3;

declare @UserInput int;
set @UserInput = 4;

with cParents as (
    select  d.ID, d.Name, d.ParentID
    from    @Data d
    where   d.ID = @UserInput
    union all
    select  d.ID, d.Name, d.ParentID
    from    cParents c
    inner join @Data d
        on  d.ID = c.ParentID
),
cChildren as (
    select  d.ID, d.Name, d.ParentID
    from    @Data d
    where   d.ID = @UserInput
    union all
    select  d.ID, d.Name, d.ParentID
    from    cChildren c
    inner join @Data d
        on  d.ParentID = c.ID
)
select  RecordType='self', d.ID, d.Name, ParentName=isnull(p.Name,'')
from    @Data d
left join @Data p
    on  p.ID = d.ParentID
where   d.ID = @UserInput

union all

select  RecordType='parents', d.ID, d.Name, ParentName=isnull(p.Name,'')
from    cParents d
left join @Data p
    on  p.ID = d.ParentID
where   d.ID <> @UserInput

union all

select  RecordType='children', d.ID, d.Name, ParentName=isnull(p.Name,'')
from    cChildren d
left join @Data p
    on  p.ID = d.ParentID
where   d.ID <> @UserInput;
@数据代表示例数据,@UserInput是输入变量。 我添加了一个RecordType来澄清记录部分的含义。
它在SQL Server 2008上进行了测试,应该在2005年可以使用,但在2000年不能使用。

不按用户输入进行过滤,如请求所示对不起,是真的。当我有更多详细信息时,我将进行调整。用户不知道深度。如果深度为1,则用户可以轻松使用join或union关键字来获取值。但用户不知道深度。可能需要使用递归技术。我不知道如何在sql上使用递归技术。很抱歉,我仍然不清楚您的筛选器应该如何工作。如果其他人能理解,也许他们可以帮助。请你看看上面的描述。如果你花些时间阅读我的问题描述,希望你不难理解。基于该ID显示列表的逻辑是什么?我能看到的唯一模式是输入ID是第一个。我有两个基于父子关系的表需要显示详细记录。很抱歉,我忘了告诉您详细表。希望您理解,为什么我需要这种类型的查询如何在GONeale的点上不使用CTEAgree来获得结果。虽然有一些模糊的想法,但需要澄清。如果输入为ID=2,输出将是什么?运行上述语法以显示这些错误。Msg 156,15级,状态1,第4行关键字“WITH”附近的语法不正确。Msg 137,级别15,状态2,第8行必须声明变量'@data'。Msg 137,级别15,状态2,第14行必须声明变量“@data”。@shamim:replace@data/dbo.YourTable为您的表名设置表名后显示以下错误:Msg 156,级别15,状态1,第4行关键字“with”附近语法不正确。Msg 170,级别15,状态1,第15行第15行:“,”附近的语法不正确。@Shamim:您是在SQL Server 2000还是2005上尝试此操作??这在SQL Server 2000上不起作用-仅在2005年…我使用Server 2005。但我不能使用上述语法,上面的语法显示错误…Msg 156,级别15,状态1,第4行关键字“WITH”附近的语法不正确。Msg 170,15级,状态1,第15行,第15行:靠近“,”的语法不正确。Msg 156,15级,状态1,过程spGetParent,第8行,关键字“WITH”附近的语法不正确。Msg 170,第15级,状态1,过程spGetParent,第20行,第20行:“,”附近的语法不正确。