[英]How to select a single record per group based on multiple MAX conditions?
[英]SQL select MAX to find single record of a group
我有很多記錄代表相同的信息,但是其他表的鍵不同。 我需要按它們的公共屬性(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
uck,我不喜歡這種設置。 您違反了良好的規范化實踐,並且有一些固有的假設需要“外部”知識。 但是,您說過不能更改它...
我認為以下方法應該有效(供應商中立):
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()
傳遞GUID(什么?)-
您至少有三個選擇:
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
嘗試這個:
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
如果只想選擇,則可以使用以下查詢-
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
您可以使用交叉申請進行選擇。 交叉應用基本上選擇具有匹配的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列。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.