我有许多记录代表相同的信息,但与其他表的键不同。我需要按照它们的公共属性(Att1,Att2,Att3)对这些记录进行分组,然后选择所有公共记录的单个RecordID作为这些公共记录的masterID。仅当masterID为null时,才需要将masterID添加到它所代表的每个记录中。我无法更改数据结构,所有表值都是GUID。我试过MAX,但是我没有得到分组。
TableA (Current State)
RecordID Att1 Att2 Att3 MasterID
1 A B C
2 A B C
3 A B C
4 D E F
5 D E F
6 D E F
7 G H I 7
8 G H I 7
9 G H I 7
更新:添加了预期结果。
TableA (Expected Result)
RecordID Att1 Att2 Att3 MasterID
1 A B C 1
2 A B C 1
3 A B C 1
4 D E F 4
5 D E F 4
6 D E F 4
7 G H I 7
8 G H I 7
9 G H I 7
答案 0 :(得分:3)
哎呀,我不喜欢这个设置。你违反了良好的规范化实践,并且存在一些需要“外部”知识的固有假设。但是,你已经说过你不能改变它......
我相信以下内容应该有效(供应商中立):
UPDATE TableA as a SET masterId = (SELECT MIN(b.recordId)
FROM TableA as b
WHERE b.att1 = a.att1
AND b.att2 = a.att2
AND b.att3 = a.att3)
WHERE masterId IS NULL
<小时/> 编辑:
一旦发现可以订购GUID,但无法传递MIN()
或MAX()
(什么?) -
你有(至少)三个选择:
SELECT MIN(CAST(b.recordId as CHAR(36)))
)。但是,这很可能表现不佳,仅仅是因为它会抛出每一行(参见,这就是为什么内部ID最好是简单的整数)。尝试此供应商中立声明:
UPDATE TableA as a SET masterId = (SELECT b.recordId
FROM TableA as b
LEFT JOIN TableA as c
ON c.att1 = b.att1
AND c.att2 = b.att2
AND c.att3 = b.att3
AND c.recordId < b.recordId
WHERE b.att1 = a.att1
AND b.att2 = a.att2
AND b.att3 = a.att3
AND b.recordId <= a.recordId
AND c.recordId IS NULL)
WHERE masterId IS NULL
SQL Server还有这个更惯用的版本:
UPDATE Updating
SET Updating.masterId = Origin.recordId
FROM TableA Updating
JOIN (TableA Origin
LEFT JOIN TableA Exclusion
ON Exclusion.att1 = Origin.att1
AND Exclusion.att2 = Origin.att2
AND Exclusion.att3 = Origin.att3
AND Exclusion.recordId < Origin.recordId)
ON Exclusion.recordId IS NULL
AND Origin.att1 = Updating.att1
AND Origin.att2 = Updating.att2
AND Origin.att3 = Updating.att3
WHERE Updating.masterId IS NULL
答案 1 :(得分:1)
试试这个:
UPDATE m
SET
MasterID = s.RecordID
FROM TableA AS m
INNER JOIN (
SELECT Att1, Att2, Att3, MIN(RecordID) AS RecordID
FROM TableA
GROUP BY Att1, Att2, Att3
) AS s
ON m.Att1 = s.Att1 AND m.Att2 = s.Att2 AND m.Att3 = s.Att3
WHERE
MasterID IS NULL
答案 2 :(得分:1)
如果您只想选择,则可以使用以下查询 -
select recordid ,
Att1,
Att2,
Att3,
COALESCE( MasterID , (select min(a2.recordid) from tableA a2
where a2.Att1 = a1.Att1
and a2.Att2= a1.Att2
and a1.Att3 = a2.Att3))
from TableA a1
答案 3 :(得分:0)
您可以使用交叉申请进行选择。 cross apply基本上选择匹配Att1,Att2和Att3的最低RecordID,并将RecordID作为名为MasteRID的列加入。
WITH temp as (SELECT RecordID, Att1, Att2, Att3, c.MasterID FROM dbo.TableA b
CROSS APPLY (SELECT TOP 1 RecordID as MasterID
FROM dbo.TableA a
WHERE a.Att1=b.Att1
AND a.Att2=b.Att2 AND a.Att3=b.Att3
ORDER BY RecordID) c)
UPDATE TableA
SET MasterID=t.MasterID
FROM temp t
WHERE RecordID=t.RecordID
更新将使用适当的RecordID更新每个RecordID条目的MasterID列。