簡體   English   中英

根據日期列選擇非重復項 - SQL Server

[英]Selecting non-duplicates based on date column - SQL Server

我有兩個這樣的表:

Clients                 
ID  |  Name  |  DOB      | etc...   
1   | Andy   | 26/12/90  |
2   | Bob    | 27/10/93  |
3   | Callum | 11/12/97  |
4   | Dave   | 06/01/64  |
5   | Andy   | 01/06/89  |

ClientRecordEntries
ID | cID | DateSaved      | Address               | Phone Number | Blah blah blah...
1  | 1   | 06/03/13 03:01 | 1 High Street         | 0754812374   |
2  | 1   | 06/03/13 04:05 | 1 High Street         | 0854123474   |
3  | 5   | 06/03/13 04:23 | 742 Evergreen Terrace | 0548162384   |
4  | 4   | 06/03/13 03:27 | 5 Spooner St          | 0512348455   |
5  | 3   | 06/03/13 05:03 | 6 Cromwell Avenue     | 0745289324   |
6  | 5   | 06/03/13 05:04 | 743 Evergreen Terrace | 0548162384   |
7  | 5   | 06/03/13 05:17 | 743 Evergreen Terrace | 0461238489   |
8  | 2   | 06/03/13 05:18 | 45 High Street        | 0682374988   |

這個想法是關於每個客戶端的一些基本的,不可變的信息存儲在第一個表中,更詳細的信息存儲在第二個表中。 編輯客戶端數據時,不是在ClientRecordEntries中編輯其對應的行,而是添加一個全新的行(帶有時間戳),以便記錄以前所做的所有更改。 因此,每個客戶端的當前信息是第二個表中與其ID對應且具有最新時間戳的行。

例如,ID為5的客戶住在743 Evergreen Terrace,他的電話號碼是0461238489,他的詳細信息已經被編輯了兩次(因此輸入了三次 - 第二個表的第3,6和7行。)

我的問題是,如何在第一個表上使用第二個表加入查詢結果,但除了每個客戶端的最新信息外,還要刪除所有行? 例如,在上面的示例中,我想為每個名為“Andy”的人選擇當前信息,所以我想要結果:

Name |  DOB     | Address               | Phone Number | etc...
Andy | 26/12/90 | 1 High  Street        | 0854123474   |
Andy | 01/06/89 | 743 Evergreen Terrace | 0461238489   |

我猜我想要SELECT * FROM Clients JOIN ClientRecordEntries ON Clients.ID=ClientRecordEntries.cID WHERE Name='Andy'...然后使用MAX(SavedDate)但我卡住了。 有什么建議么?

(是的,我意識到SELECT *會顯示比我上面輸入的列更多的列,但我簡化了一些事情。)

我正在使用SQL Server,如果它有所作為。

通過術語刪除重復項 ,如果您只是想在投影期間隱藏重復值,則可以在此處使用窗口函數,

WITH records AS
(
    SELECT  ID,cID,DateSaved,Address ,[Phone Number],
            ROW_NUMBER() OVER (PARTITION BY cid ORDER BY DateSaved DESC) rn
    FROM    ClientRecordEntries
)
SELECT  a.*, DateSaved,Address ,[Phone Number]
FROM    Clients a
        INNER JOIN records b
            ON a.ID = b.cid
WHERE   b.rn = 1

嘗試這個。 您可以使用CTEROW_NUMBER()來實現此目的。

WITH CTE  
AS  
(  
   SELECT *,  
      ROW_NUMBER() OVER (PARTITION BY CID ORDER BY DateSaved DESC) RN  
   FROM ClientRecordEntries  
)  

SELECT *   
FROM Clients C  
INNER JOIN CTE CT  
ON CT.CID = C.ID  
WHERE C.NAME = 'Andy' 
AND RN = 1  

SQL FIDDLE DEMO

除非您有少量客戶端,否則應在表ClientRecordEntries中添加一個標志,以指示出於性能原因哪個行是每個客戶端的最新行,並添加一個覆蓋此標志和cId列的索引。

由於很少需要查看這些舊信息,另一種解決方案是使用第三個表來陳舊這些舊信息。 通常,會有一個表來保存其他表中的所有舊信息; 以及其他一些信息,例如編輯時間和完成編輯的用戶。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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