首页 > 解决方案 > 使用外部应用分配最低记录 ID

问题描述

假设我有这些表:

CREATE TABLE Employee (ID int, EmployeeIdentifier varchar(100),ManagerIdentifier varchar(100))
CREATE TABLE EmployeeManager (ID int, EmployeeID varchar(100))

INSERT Employee
VALUES
(1,'apple','apple'),
(2,'banana','apple'),
(3,'citrus','apple'),
(4,'grape','grape'),
(5,'grape','grape'),
(6,'grape','grape')

INSERT EmployeeManager
VALUES
(1,1),
(2,1),
(3,1),
(4,4),
(5,5),
(6,5)

对于Employee.ID IN (1,2,3), 中的记录EmployeeManager看起来不错。但在Employee.ID IN (4,5,6)我们可以看到许多重复。我们不允许从Employee表中删除任何记录。但是我们可以自由分配EmpoyeeManager.EmployeeID价值。由于只有一个实际记录,Grape其余记录是重复的,我想从表中所有重复的葡萄记录中分配EmpoyeeManager.EmployeeID一个最小值,也就是 4。Employee.IDEmployee

我有这个疑问,

UPDATE d SET EmployeeID = l.ID
FROM dbo.EmployeeManager d
INNER JOIN Employee s on d.ID=s.ID
OUTER APPLY (
    
                SELECT  ID
                FROM  Employee l 
                WHERE s.ManagerIdentifier=l.EmployeeIdentifier
) l
WHERE 
EXISTS (
                SELECT d.EmployeeID
                EXCEPT
                SELECT l.ID
            )

如果您继续运行它,您将看到EmployeeManager.EmployeeIDID (4,5,6) 的值将不断变化。我如何更新上面的更新语句以分配给Employee.ID所有 EmployeeManager.ID (4,5,6) 的最小值,也就是 4?

我们不允许运行一次性修复脚本,因为上表的损坏数据会不断出现。

运行以上更新语句后所需的输出应该是

在此处输入图像描述

标签: sqlsql-servertsql

解决方案


您需要在TOP (1)ORDER BY查询中选择特定行

UPDATE d SET EmployeeID = l.ID
FROM dbo.EmployeeManager d
INNER JOIN Employee s on d.ID=s.ID
OUTER APPLY (
                SELECT TOP (1) ID
                FROM  Employee l 
                WHERE s.ManagerIdentifier = l.EmployeeIdentifier
                ORDER BY ID
) l
WHERE 
EXISTS (
                SELECT d.EmployeeID
                EXCEPT
                SELECT l.ID
            )
  • 您似乎有一个规范化问题,因为Manager在两个地方定义
  • 我建议你为你的表使用更好的别名,它们不是很容易记住
  • 您可以将您的更改OUTERCROSS,然后您可以使用标准<>而不是EXISTS/EXCEPT
CROSS APPLY (
                SELECT TOP (1) ID
                FROM  Employee l 
                WHERE s.ManagerIdentifier = l.EmployeeIdentifier
                ORDER BY ID
) l
WHERE d.EmployeeID <> l.ID

推荐阅读