我有一个表(t_budget),其中列出了负责给定预算的员工的 ID 以及分配的金额和预算支出。该表是一个较大查询的结果,该查询首先针对 HR 数据以获取预算所有者列表,然后连接到支出表(预算所有者 = 员工 ID)以导入支出。问题在于,部分支出来自非预算负责人的员工。在这种情况下,我需要将支出映射到该员工最近的预算所有者。
在将支出与最近的员工匹配之前输出表。目标是让第二行 (Budget_Owner = 10) 显示员工 8 的支出 (200 美元),因为该预算所有者是最接近支出负责人。
+--------------+------------------+-------+
| Budget_Owner | Allocated_Budget | Spend |
+--------------+------------------+-------+
| 1 | 500 | $100 |
+--------------+------------------+-------+
| 10 | 600 | $0 | '<--- $200
+--------------+------------------+-------+
第二个表(t_spend)有employee_id、spend和格式为
id1/id2/..../idn
(ID_Path_Up)的字符串,该字段遵循从员工到所有者的经理链的ID(我,经理,跳过经理,... ..,首席执行官 ID)。由于“ID = 8”(第二行)不是预算所有者,因此需要将支出分配给 t_budget 中存在的 ID_Path_Up
中最接近的 id。
+-------------+-------+-------------+
| Employee_ID | Spend | ID_Path_Up |
+-------------+-------+-------------+
| 1 | 100 | 1/2/3/4/5/6 |
+-------------+-------+-------------+
| 8 | 200 | 8/9/10/11 |
+-------------+-------+-------------+
如果有任何其他工具,我会使用循环,但我不确定是否可以在 SQL 中完成。如何确定从字符串到列表的第一个“id”匹配?
使用以下内容创建一个函数:
CREATE FUNCTION [dbo].[fn_ParseDelimitedList] (@parseChar char(1), @strString varchar(4000))
RETURNS @Result TABLE(Value int)
AS
BEGIN
DECLARE @x XML
SELECT @x = CAST('<A>'+ REPLACE(REPLACE(@strString, ' ', ''),@parseChar,'</A><A>')+ '</A>' AS XML)
INSERT INTO @Result
SELECT distinct t.value('.', 'int') AS inVal
FROM @x.nodes('/A') AS x(t)
RETURN
END
然后,在您的查询中,执行以下操作:
SELECT t2.[Employee_ID], t3.[Budget_Owner], t2.[Spend] FROM spend_table t2
LEFT JOIN budget_table t1 on t2.[Employee_ID] = t1.[Budget_Owner]
JOIN budget_table t3 on t3.[Budget_Owner] in (select * from [fn_ParseDelimitedList]('/', t2.[ID_Path_Up]))
这样,如果您愿意,您还可以添加一些内容来聚合和汇总。