Sql server 将1列的值查找到另一列中,如果存在,则将该值存储在第3列中

Sql server 将1列的值查找到另一列中,如果存在,则将该值存储在第3列中,sql-server,vlookup,hierarchical-data,Sql Server,Vlookup,Hierarchical Data,我试图在表中的一行中实现层次结构 我有一个包含两个主列的表,Emp(员工)和Mgr(经理)。我需要对mgr值进行vlookup(SQL Server中的eqivalent)并检查emp列表中是否存在,如果存在,我需要将匹配的mgr值放入MH1中。然后将vlookup(SQL Server中的等效项)MH1再次放入emp列表中,如果匹配,则将其相应的mgr值放入MH2中,依此类推。。直到没有mgr值匹配为止。下面是示例结果的图像 方法1:使用递归cte。虽然速度很快,但您需要在示例输入表中建立一

我试图在表中的一行中实现层次结构

我有一个包含两个主列的表,Emp(员工)和Mgr(经理)。我需要对mgr值进行vlookup(SQL Server中的eqivalent)并检查emp列表中是否存在,如果存在,我需要将匹配的mgr值放入MH1中。然后将vlookup(SQL Server中的等效项)MH1再次放入emp列表中,如果匹配,则将其相应的mgr值放入MH2中,依此类推。。直到没有mgr值匹配为止。下面是示例结果的图像


方法1:使用递归cte。虽然速度很快,但您需要在示例输入表中建立一个完整的层次关系,才能获得理想的输出:

WITH CTE(HierarchyStr, Emp, Mgr) 
AS (
    SELECT CAST(Emp AS nvarchar(1000)), Emp, Mgr 
        FROM T where Mgr IS NULL
    UNION ALL
    SELECT CAST(T.Emp + ', ' + CTE.HierarchyStr AS nvarchar(1000)), T.Emp, T.Mgr 
        FROM T JOIN CTE on T.Mgr = CTE.Emp  
)
SELECT 
    HierarchyStr
FROM 
    CTE;
方法2:这个非常直观的TSQL可能更适合您所需的输出,但在大型表上速度较慢,请小心使用:

DECLARE @MhColName varchar(10) = 'Mgr';
DECLARE @OldMhColName varchar(10);
DECLARE @I int = 0;
DECLARE @Done bit = 0;
DECLARE @CheckSql nvarchar(1000);

SELECT Emp, Mgr INTO #ResultTable FROM T;

WHILE (@Done = 0)
BEGIN
    SET @OldMhColName = @MhColName;
    SET @I = @I + 1;
    SET @MhColName = 'MH' + CAST(@I AS varchar(2));

    EXEC('ALTER TABLE #ResultTable ADD ' + @MhColName + ' nvarchar(30)');

    EXEC('UPDATE R1 SET ' + @MhColName + ' = R2.Mgr 
            FROM 
                #ResultTable R1, #ResultTable R2
            WHERE R1.' + @OldMhColName + ' = R2.Emp');

    SET @CheckSql = 
         'IF NOT EXISTS(SELECT * FROM #ResultTable WHERE ' + @MhColName + ' IS NOT NULL)
          BEGIN
            ALTER TABLE #ResultTable DROP COLUMN ' + @MhColName + ';
            SET @Done = 1;
          END';
    EXECUTE sp_executesql @CheckSql, N'@Done bit OUTPUT', @Done = @Done OUTPUT;
END;

SELECT * FROM #ResultTable;
样本输入:

Emp     Mgr
Mark    Thomas
Thomas  Bob
Bob     Kim
Kim     Tim
Tim     Kelvin
Andrew  NULL
Kelvin  Andrew
方法1输出:

HierarchyStr
Andrew
Kelvin, Andrew
Tim, Kelvin, Andrew
Kim, Tim, Kelvin, Andrew
Bob, Kim, Tim, Kelvin, Andrew
Thomas, Bob, Kim, Tim, Kelvin, Andrew
Mark, Thomas, Bob, Kim, Tim, Kelvin, Andrew
方法2输出:

Emp     Mgr     MH1     MH2     MH3     MH4     MH5
Mark    Thomas  Bob     Kim     Tim     Kelvin  Andrew
Thomas  Bob     Kim     Tim     Kelvin  Andrew  NULL
Bob     Kim     Tim     Kelvin  Andrew  NULL    NULL
Kim     Tim     Kelvin  Andrew  NULL    NULL    NULL
Tim     Kelvin  Andrew  NULL    NULL    NULL    NULL
Andrew  NULL    NULL    NULL    NULL    NULL    NULL
Kelvin  Andrew  NULL    NULL    NULL    NULL    NULL

您可以通过三个独立的
UPDATE
语句来完成此操作,将表自动连接回
Emp

更新t1
设置MH1=t2.Mgr
来自表t1
在t2.Emp=t1.Mgr上连接表t2;
更新t1
设置MH2=t2.Mgr
来自表t1
在t2.Emp=t1.MH1上连接表t2;
更新t1
设置MH3=t2.Mgr
来自表t1
在t2.Emp=t1.MH2上连接表t2;

如您的示例所示,层次结构深度是否始终最大为3?根据问题指南,请说明您尝试了什么,并告诉我们您发现了什么(在本网站或其他地方),以及为什么它不能满足您的需要。Tim Mylott,层次结构深度可以最大为10。Dale K,我尝试使用;使用创建带有emp、mgr的临时表,然后在此基础上,我尝试与临时表和mgr字段上的原始表进行左连接。尝试进行多个左连接,但无法实现层次结构
Emp     Mgr     MH1     MH2     MH3     MH4     MH5
Mark    Thomas  Bob     Kim     Tim     Kelvin  Andrew
Thomas  Bob     Kim     Tim     Kelvin  Andrew  NULL
Bob     Kim     Tim     Kelvin  Andrew  NULL    NULL
Kim     Tim     Kelvin  Andrew  NULL    NULL    NULL
Tim     Kelvin  Andrew  NULL    NULL    NULL    NULL
Andrew  NULL    NULL    NULL    NULL    NULL    NULL
Kelvin  Andrew  NULL    NULL    NULL    NULL    NULL