我写了一个可以工作并完成我想要的查询,但我无法弄清楚为什么逻辑工作正常。我无法分享确切的表格,因为信息很敏感,但我会在下面重新创建。
Table_A有三列:
Employee_ID,
Condition,
B_Confirmed_Flag
Table_B有两列:
Employee_ID,
Condition
我的目标是编写一个更新语句,只要Employee_ID - >,就会将Table_A中的B_Confirmed_Flag更新为1。条件组合存在于表__B中。
更新声明:
UPDATE TABLE_A
SET B_Confirmed_Flag = 1
FROM TABLE_A
WHERE TABLE_A.Condition IN (SELECT TABLE_B.CONDITION
FROM TABLE_B
WHERE TABLE_B.EMPLOYEE_ID = TABLE_A.EMPLOYEE_ID)
此更新声明似乎有效,但我对逻辑感到困惑。我会认为,使用此更新语句,我将不必要地标记某些行,其中Table_B中的多个Employee_ID在Condition列中具有相同的值。但是,查询对我有用。
谢谢!
答案 0 :(得分:2)
要回答它是如何工作的,请按照与此类似的方式细分查询: 对于表A中的每条记录,子查询表B中员工ID匹配的所有记录。然后,如果表A中的记录具有子查询中存在的条件,则更新发生。有效地为您提供employeeID和Condition的连接条件。
正如其他人已经回答的那样,重写您的查询将更容易阅读,并可能表现更好。
答案 1 :(得分:2)
让我们假设您有这样的虚拟数据:
CREATE TABLE #table_A (Employee_ID INT,
Condition VARCHAR(1),
B_Confirmed_Flag BIT
)
CREATE TABLE #table_B (Employee_ID INT,
Condition VARCHAR(1)
)
INSERT INTO #table_A (Employee_ID, Condition, B_Confirmed_Flag)
VALUES
(1, 'A', 0),
(2, 'A', 0),
(3, 'A', 0),
(4, 'B', 0),
(5, 'B', 0),
(6, 'B', 0),
(7, 'B', 0)
INSERT INTO #table_B (Employee_ID, Condition)
VALUES
(1, 'A'),
(3, 'A'),
(5, 'B'),
(6, 'B')
如果您运行这两个查询并启用执行计划,您将看到差异。
select *
FROM #TABLE_A
WHERE #TABLE_A.Condition IN (SELECT #TABLE_B.CONDITION
FROM #TABLE_B
WHERE #TABLE_B.EMPLOYEE_ID = #TABLE_A.EMPLOYEE_ID)
select *
FROM #TABLE_A
WHERE #TABLE_A.Condition IN (SELECT #TABLE_A.CONDITION
FROM #TABLE_A
WHERE #TABLE_A.EMPLOYEE_ID IN (1,4))
第一个是你的,第二个是样本。听起来你期望你的查询像第二个一样工作。如果查询的IN部分应返回应更新table_A中所有记录的值,为什么不呢?如果检查执行计划并查看嵌套循环谓词,则可以看到查询正在查看条件以及员工ID。这就是为什么更新只更新它在表B中找到的员工以及他们的状况。
答案 2 :(得分:1)
它的工作原理是因为逐行处理更新
这应该更有效率
UPDATE TABLE_A
SET B_Confirmed_Flag = 1
FROM TABLE_A
WHERE exists ( SELECT 1
FROM TABLE_B
WHERE TABLE_B.EMPLOYEE_ID = TABLE_A.EMPLOYEE_ID
and TABLE_B.Condition = TABLE_A.CONDITION
)
and (B_Confirmed_Flag <> 1 or B_Confirmed_Flag is null)
如果那些是pk那么
UPDATE TABLE_A
SET B_Confirmed_Flag = 1
FROM TABLE_A
JOIN TABLE_B
ON TABLE_B.EMPLOYEE_ID = TABLE_A.EMPLOYEE_ID
and TABLE_B.Condition = TABLE_A.CONDITION
and (B_Confirmed_Flag <> 1 or B_Confirmed_Flag is null)