Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 获取自引用表上的第n级_Sql_Sql Server - Fatal编程技术网

Sql 获取自引用表上的第n级

Sql 获取自引用表上的第n级,sql,sql-server,Sql,Sql Server,我有一个自参考表,最多有5个级别 groupid | parentid | detail --------- | --------- | --------- Group A | Highest | nope Group B | Group A | i need this Highest | NULL | nope Group C | Group B | nope Group D | Group C | nope 我有一个事务表,它

我有一个自参考表,最多有5个级别

groupid   | parentid  | detail
--------- | --------- | ---------
Group A   | Highest   | nope 
Group B   | Group A   | i need this  
Highest   | NULL      | nope 
Group C   | Group B   | nope 
Group D   | Group C   | nope 
我有一个事务表,它在上面的表中查找groupid以检索详细信息值,其中groupid=groupb。事务表中groupid的值仅在groupb到D之间,永远不会再高

txnid     | groupid   | desired   | desired
--------- | --------- | --------- | ---------
1         | Group D   | Group B   | i need this
2         | Group B   | Group B   | i need this
3         | Group C   | Group B   | i need this
4         | Group B   | Group B   | i need this
我的T-SQL脚本应该如何获得所需的列?我可以多次加入自引用表,直到B组在我需要加入的时间上不一致为止


非常感谢任何想法

我仍然不清楚您如何知道哪个是B组,我想这是一条记录,它的父项为null

id |组id |详细信息| -: | :------ | :---------- 1 | b |我需要这个 2 | c |我需要这个 3 | c |我需要这个 4 | d |我需要这个 我需要这个
DBFIDLE

为什么要停在A组上?所需的
列的目的是什么?您知道事务表上每个groupid的级别吗?@TimBiegeleisen这是公司级别的一个层次结构。例如:最高级别-公司,A组-部门,B组-部门,C组-团队,D组-个人。道歉,如果它的困惑,因为我不得不掩盖实际的陈述。在我的示例中,所需列应采用部门的值。我需要将其存储在交易中,以便稍后在交易表中应用子集/行级别权限。您没有回答我的任何问题。由于没有其他人回答,您的问题可能不清楚,这一点我是正确的。@transactions表上示例中的MCNET最多有3个级别(B、C、D)。它们的值不高于B组
create table org(groupid char(1), parentid char(1), details varchar(20));
insert into org values
('a', null, 'nope'),('b', 'a', 'I need this'),('c', 'b', 'nope'),('d', 'c', 'nope'),('e', 'd', 'nope');

create table trans(id int, groupid char(1));
insert into trans values
(1, 'b'),(2, 'c'),(3, 'c'),(4, 'd'),(5, 'e');
GO
10 rows affected
with all_levels as
(
    select     ob.groupid groupid_b, oc.groupid groupid_c, 
               od.groupid groupid_d, oe.groupid groupid_e, 
               ob.details
    from       org ob
    inner join org oc
    on         oc.parentid = ob.groupid
    inner join org od
    on         od.parentid = oc.groupid
    inner join org oe
    on         oe.parentid = od.groupid
    where      ob.parentid is not null
) select * from all_levels;

GO
groupid_b | groupid_c | groupid_d | groupid_e | details :-------- | :-------- | :-------- | :-------- | :---------- b | c | d | e | I need this
--= build a 4 levels row
with all_levels as
(
    select     ob.groupid groupid_b, oc.groupid groupid_c, 
               od.groupid groupid_d, oe.groupid groupid_e, 
               ob.details
    from       org ob
    inner join org oc
    on         oc.parentid = ob.groupid
    inner join org od
    on         od.parentid = oc.groupid
    inner join org oe
    on         oe.parentid = od.groupid
    where      ob.parentid is not null
) 
    --= no matter what groupid returns b group details
    , only_b as
    (
        select groupid_b as groupid, groupid_b, details from all_levels
        union all
        select groupid_c as groupid, groupid_b, details from all_levels
        union all
        select groupid_d as groupid, groupid_b, details from all_levels
        union all
        select groupid_e as groupid, groupid_b, details from all_levels
    )
    --= join with transactions table
    select     id, t.groupid, groupid_b, ob.details
    from       trans t
    inner join only_b ob
    on         ob.groupid = t.groupid;
GO
id | groupid | groupid_b | details -: | :------ | :-------- | :---------- 1 | b | b | I need this 2 | c | b | I need this 3 | c | b | I need this 4 | d | b | I need this 5 | e | b | I need this
create function findDetails(@groupid char(1))
returns varchar(100)
as
begin
    declare @parentid char(1) = '1';
    declare @next_parentid char(1) = '1';
    declare @details varchar(100) = '';

    while @next_parentid is not null
    begin
        select     @details = org.details, @parentid = org.parentid, @next_parentid = op.parentid
        from       org
        inner join org op
        on         op.groupid = org.parentid
        where      org.groupid = @groupid

        set @groupid = @parentid;
    end

    return @details;
end
GO
select id, groupid, dbo.findDetails(groupid) as details_b
from   trans;
GO
id | groupid | details_b -: | :------ | :---------- 1 | b | I need this 2 | c | I need this 3 | c | I need this 4 | d | I need this 5 | e | I need this