1

私はこのような2つのテーブルを持っています:

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   |

各クライアントに関する基本的な不変の情報が最初のテーブルに格納され、より詳細な情報が2番目のテーブルに格納されるという考え方です。ClientRecordEntriesの対応する行を編集するのではなく、クライアントのデータを編集すると、以前に行われたすべての変更の記録を保持するために、完全に新しい行が(タイムスタンプ付きで)追加されます。したがって、各クライアントの現在の情報は、IDに対応し、最新のタイムスタンプを持つ2番目のテーブルの行です。

たとえば、ID5のクライアントは743Evergreen Terraceに住んでおり、彼の電話番号は0461238489であり、彼の詳細は2回編集されています(したがって、2番目の表の3、6、7行目に3回入力されています)。

私の質問は、最初のテーブルのクエリの結果を2番目のテーブルと結合し、クライアントごとの最新情報を除くすべての行を削除するにはどうすればよいですか?たとえば、上記の例で、「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 *、上で入力したよりも多くの列が表示されることに気付きましたが、単純化しています。)

違いが生じる場合は、SQLServerを使用しています。

4

3 に答える 3

1

重複を削除するという用語は、投影中に重複値のみを非表示にすることを意味する場合、これに対してウィンドウ関数を使用できます。

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
于 2013-03-06T09:21:10.910 に答える
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

于 2013-03-06T09:43:14.890 に答える
1

クライアントの数が少ない場合を除いて、テーブルClientRecordEntriesにフラグを追加して、パフォーマンス上の理由から各クライアントの最新の行を示し、このフラグとcId列をカバーするインデックスを追加する必要があります。

この古い情報を確認する必要があることは非常にまれであるため、別の解決策は、この古い情報を古いものにするために3番目のテーブルを使用することです。多くの場合、他のテーブルからのすべての古い情報を保持する単一のテーブルがあります。版の時間とそれをしたユーザーのような他のいくつかの情報と一緒に。

于 2013-03-06T10:37:25.713 に答える