将 1 列的值查找到另一列中,如果存在,则将该值存储在第 3 列中
Lookup values of 1 column into another and if exists store the value in 3rd column
我正在尝试在 table
中的单行中实现层次结构
我有一个 table,其中包含 2 个主要列,Emp(Employee) 和 Mgr(Manager)。我需要对 mgr 值进行 vlookup(在 SQL 服务器中等效)并检查 emp 列表中是否存在,如果存在,我需要将匹配的 mgr 值放入 MH1。然后再次在 emp 列表中进行 vlookup(相当于 SQL 服务器)MH1,如果匹配,则将其相应的 mgr 值放入 MH2 中,依此类推。直到没有 mgr 值匹配。下面是示例结果的图像
Emp Mgr MH1 MH2 MH3
Mark Thomas Bob Kim Tim
Robert Clain Barry Murray
Chris Crain Kale Kelvin
Andrew
Thomas Bob
Clain Barry
Crain Kale
Murray Tom
Bob Kim
Kim Tim
Kale Kelvin
Barry Murray
方法一:使用递归cte。它速度很快,但您需要在示例输入 table 中有完整的层次结构关系才能获得理想的输出:
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 可能更适合您所需的输出,但它在大型 tables 上会很慢,请谨慎使用:
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
语句执行,将 table 自行连接回 Emp
UPDATE t1
SET MH1 = t2.Mgr
FROM table t1
JOIN table t2 ON t2.Emp = t1.Mgr;
UPDATE t1
SET MH2 = t2.Mgr
FROM table t1
JOIN table t2 ON t2.Emp = t1.MH1;
UPDATE t1
SET MH3 = t2.Mgr
FROM table t1
JOIN table t2 ON t2.Emp = t1.MH2;
我正在尝试在 table
中的单行中实现层次结构我有一个 table,其中包含 2 个主要列,Emp(Employee) 和 Mgr(Manager)。我需要对 mgr 值进行 vlookup(在 SQL 服务器中等效)并检查 emp 列表中是否存在,如果存在,我需要将匹配的 mgr 值放入 MH1。然后再次在 emp 列表中进行 vlookup(相当于 SQL 服务器)MH1,如果匹配,则将其相应的 mgr 值放入 MH2 中,依此类推。直到没有 mgr 值匹配。下面是示例结果的图像
Emp Mgr MH1 MH2 MH3
Mark Thomas Bob Kim Tim
Robert Clain Barry Murray
Chris Crain Kale Kelvin
Andrew
Thomas Bob
Clain Barry
Crain Kale
Murray Tom
Bob Kim
Kim Tim
Kale Kelvin
Barry Murray
方法一:使用递归cte。它速度很快,但您需要在示例输入 table 中有完整的层次结构关系才能获得理想的输出:
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 可能更适合您所需的输出,但它在大型 tables 上会很慢,请谨慎使用:
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
语句执行,将 table 自行连接回 Emp
UPDATE t1
SET MH1 = t2.Mgr
FROM table t1
JOIN table t2 ON t2.Emp = t1.Mgr;
UPDATE t1
SET MH2 = t2.Mgr
FROM table t1
JOIN table t2 ON t2.Emp = t1.MH1;
UPDATE t1
SET MH3 = t2.Mgr
FROM table t1
JOIN table t2 ON t2.Emp = t1.MH2;