簡體   English   中英

SQL選擇MAX查找組的單個記錄

[英]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(什么?)-

您至少有三個選擇:

  1. 將GUID強制轉換為可傳遞的類型(即SELECT MIN(CAST(b.recordId as CHAR(36))) )。 但是,這可能表現不佳,僅是因為它將強制轉換每一行(請參閱這就是為什么內部ID最好是簡單整數的原因)。
  2. 嘗試以下與供應商無關的聲明:

     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 
  3. 對於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 

    SQL Fiddle示例

嘗試這個:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM