Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.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 具有可传递数据的更新查询中的自联接_Sql_Sql Server_Tsql_Common Table Expression_Recursive Query - Fatal编程技术网

Sql 具有可传递数据的更新查询中的自联接

Sql 具有可传递数据的更新查询中的自联接,sql,sql-server,tsql,common-table-expression,recursive-query,Sql,Sql Server,Tsql,Common Table Expression,Recursive Query,我在下表中列出了员工及其同事的数据,如果有匹配的同事和其他员工,我想更新员工表中的bucketid 在这个例子中 Employee=101与Employee=103同事(即c1)匹配,因此两者的bucketid=1(即两个bucketid的最小值) Employee=102与Employee=103同事(即c3)匹配,因此两者应具有相同的bucketid,但此处应使用1更新,因为Employee=102 bucketid刚刚更改为1。在这个例子中,我们有可传递的依赖于法律的数据 (i.e. a=

我在下表中列出了员工及其同事的数据,如果有匹配的同事和其他员工,我想更新员工表中的bucketid

在这个例子中

Employee=101与Employee=103同事(即c1)匹配,因此两者的bucketid=1(即两个bucketid的最小值)

Employee=102与Employee=103同事(即c3)匹配,因此两者应具有相同的bucketid,但此处应使用1更新,因为Employee=102 bucketid刚刚更改为1。在这个例子中,我们有可传递的依赖于法律的数据

(i.e. a=b and b=c then a=c)
员工表:

EmployeeID  EmployeeName    BucketID
101         williams        1
102         williams        2
103         williams        3
104         williams        4
员工/同事表:

EmployeeID  Colleague
101         c1
101         c2
102         c3
102         c4
103         c1
103         c3
104         c7
我尝试使用这个更新查询

 update a2
 set BucketID = a1.BucketID
 from Employee a1
 inner join Emp_Colleagues c1 on a1.EmployeeID=c1.EmployeeID 
 inner join Employee a2 on a1.EmployeeName=a2.EmployeeName
 inner join Emp_Colleagues c2 on a2.EmployeeID=c2.EmployeeID
 where c1.Colleague=c2.Colleague and a1.BucketID <> a2.BucketID
但我希望在Employee表中输出如下

EmployeeID  EmployeeName    BucketID
101         williams        1
102         williams        1
103         williams        1
104         williams        4

我不认为你能在一个更新语句中做到这一点。但是,您可以使用循环不断更新,直到没有任何内容可更新:

declare @updates int = 1
while @updates > 0
begin
    update a2
        set BucketID = a1.BucketID
        from Employee a1
        inner join Emp_Colleagues c1 on a1.EmployeeID=c1.EmployeeID
        inner join Emp_Colleagues c2 on c1.Colleague=c2.Colleague
        inner join Employee a2 on a2.EmployeeID=c2.EmployeeID
        where a1.BucketID < a2.BucketID
    set @updates = @@ROWCOUNT
end
declare@updates int=1
而@updates>0
开始
更新a2
设置BucketID=a1.BucketID
来自员工a1
内部连接a1上的Emp_同事c1。EmployeeID=c1.EmployeeID
内部连接Emp_同事c1上的c2。同事=c2。同事
内部连接a2上的员工a2。EmployeeID=c2。EmployeeID
其中a1.BucketID
这是您要查找的查询

with CTE as
(
select EmployeeID as E1, EmployeeID as E2, cast('\' as varchar(MAX)) as list
from Employee
Union all
select E1, T2_2.EmployeeID, CTE.list +  CAST(E1 as varchar(MAX)) + '-' + CAST(T2_2.EmployeeID as varchar(MAX)) + '\'
from CTE
    inner join Employee_Colleague T2_1 ON CTE.E2 = T2_1.EmployeeID
    inner join Employee_Colleague T2_2 ON T2_1.Colleague = T2_2.Colleague
where CTE.list not like '%\' + CAST(E1 as varchar(MAX)) + '-' + CAST(T2_2.EmployeeID as varchar(MAX)) + '\' +'%'
)

Update T1_1
Set T1_1.BucketID = (select MIN(T1_2.BucketID) 
                        from Employee T1_2 
                            inner join CTE ON T1_1.EmployeeID = CTE.E1 AND T1_2.EmployeeID = CTE.E2
                    )
from Employee T1_1 

您尝试的查询有什么问题?它返回的是上面提到的输出,而不是我实际想要的。您需要一个递归CTE来执行此操作,因为可能存在不确定数量的转换,例如
a=b和b=c和c=d
,然后
a=d
。是的,您可以使用递归CTE编写查询@Giorgosbetosi认为我们可以通过使用递归CTE来实现这一点。。你知道吗?上面的表格中有大量的数据。我运行了这个查询,但从2天开始就无法执行。上面的查询解决了我的问题。你能帮助我使用递归查询吗。谢谢。:-)
with CTE as
(
select EmployeeID as E1, EmployeeID as E2, cast('\' as varchar(MAX)) as list
from Employee
Union all
select E1, T2_2.EmployeeID, CTE.list +  CAST(E1 as varchar(MAX)) + '-' + CAST(T2_2.EmployeeID as varchar(MAX)) + '\'
from CTE
    inner join Employee_Colleague T2_1 ON CTE.E2 = T2_1.EmployeeID
    inner join Employee_Colleague T2_2 ON T2_1.Colleague = T2_2.Colleague
where CTE.list not like '%\' + CAST(E1 as varchar(MAX)) + '-' + CAST(T2_2.EmployeeID as varchar(MAX)) + '\' +'%'
)

Update T1_1
Set T1_1.BucketID = (select MIN(T1_2.BucketID) 
                        from Employee T1_2 
                            inner join CTE ON T1_1.EmployeeID = CTE.E1 AND T1_2.EmployeeID = CTE.E2
                    )
from Employee T1_1