2017-11-22 6 views
0

独自の「参照」のみを返そうとしていますが、「姓」と「電子メール」も取り戻す必要があります。私の例では、参照に複数の顧客を関連付けることができます。現在、私のクエリは、「参照」に関連付けられたすべての顧客を引き戻します。私は顧客の1人だけの詳細が必要なので、「姓」と「メール」を使って「参照」を一度取り消したい。SQL - 複数の列で一意の単一列の固有値を取得する

以下のクエリは例ですが、これは達成しようとしているシナリオに関連しています。

この例では、 'UniqueID'は基本的にアイテムがテーブルに追加された順序です。私はこれを必要とするので、最新のレコードでフィルタリングすることができます。 'Reference'は増分ベースではないので、私はこれを使うことはできません。

本質的には、重複した「参照」のインスタンス数をカウントしたいだけですが、「参照」のインスタンスと対応する「電子メール」と「姓」のインスタンスを返し、追加された最新のレコードで並べ替えます。

各テーブルにあるものの味:

CustomerPackage: UniqueID (INT); Reference (STRING) 
Customer: FirstName (STRING); Surname (STRING); Email (STRING); Address (STRING) 
PurchaseDetails: PurchaseDate (DATE); PurchaseDescription (STRING); PurchaseType (INT) 

SQLスクリプトの例:

USE Example 
GO 

SELECT TOP 10 

CP.Reference, 
C.Surname, 
C.Email 

FROM CustomerPackage CP 

INNER JOIN Customer C ON CP.UniqueID = C.UniqueID 
INNER JOIN PurchaseDetails PD ON CP.UniqueID = PD.UniqueID 

WHERE PD.PurchaseDate > dateadd(HOUR,10,getutcdate()) and PD.PurchaseDate < dateadd(DAY,29,getutcdate()) and PD.PurchaseType = 1 

ORDER BY CP.UniqueID DESC 

出力:

Reference Surname  Email 
1XX45  Smith  [email protected] 
1XX45  Jones  [email protected] 
1XX45  Betty  [email protected] 
4B678  Reeds  [email protected] 

========== =============

必要な出力:

Reference Surname  Email 
1XX45  Smith  [email protected] 
4B678  Reeds  [email protected] 
+0

「e.e @ e.com」という電子メールが他の2つに比べて選択された理由は何ですか? –

+0

論理はありません。重複する参照のどれかを選択することができます。ただ一つの参照が返されている限り、 – Scott

+0

あなたは以下から2つの機能的な答えを選ぶことができます。 –

答えて

0

何が欲しいのは、あなたがROW_NUMBERを使用することができ、レコードの各参照グループの最新購入日を持つ単一のレコードの場合:

SELECT Reference, Surname, Email 
FROM 
(
    SELECT 
     CP.Reference, 
     CP.UniqueID, 
     C.Surname, 
     C.Email, 
     ROW_NUMBER() OVER (PARTITION BY CP.Reference ORDER BY PD.PurchaseDate DESC) rn 
    FROM CustomerPackage CP 
    INNER JOIN Customer C 
     ON CP.UniqueID = C.UniqueID 
    INNER JOIN PurchaseDetails PD 
     ON CP.UniqueID = PD.UniqueID 
    WHERE 
     PD.PurchaseDate > dateadd(HOUR,10,getutcdate()) AND 
     PD.PurchaseDate < dateadd(DAY,29,getutcdate()) AND 
     PD.PurchaseType = 1 
) t 
WHERE rn = 1 
ORDER BY 
    UniqueID DESC; 
+0

これはすべての答えのうち、この1つが働いた。私は他の人たちも働いていただろうと思っていますが、テーブルのサイズのために他のクエリが長すぎます。これは28秒しかかかりませんでした。ありがとう – Scott

1

私はあなたが欠けているすべてのRow_Numberだと思います

;WITH cteX 
AS(
    SELECT TOP 10 
    RN = ROW_NUMBER()OVER(PARTITION BY CP.Reference ORDER BY CP.UniqueId DESC), 
    CP.Reference, 
    C.Surname, 
    C.Email, 
    CP.UniqueId 

    FROM CustomerPackage CP 

    INNER JOIN Customer C ON CP.UniqueID = C.UniqueID 
    INNER JOIN PurchaseDetails PD ON CP.UniqueID = PD.UniqueID 

    WHERE PD.PurchaseDate > dateadd(HOUR,10,getutcdate()) and PD.PurchaseDate < dateadd(DAY,29,getutcdate()) and PD.PurchaseType = 1 
) 
SELECT 
    Reference 
    ,Surname 
    ,Email 
FROM cteX X 
WHERE X.RN = 1 
ORDER BY UniqueId DESC 
0

BY条件GROUPあなたが探していると呼ばれています。あなたの状況では、CP.Referenceでグループ化する必要があります。これにより、各参照のすべてのデータが集計されます。この結果、あなたのクエリは姓と電子メール(1XX45は3つの異なる姓と電子メールを持っている)のために表示するデータを知らないでしょう。あなたのケースでは、ただ一つの姓や電子メールを表示したいので、これらのレコードの最高値を選ぶことができます。

USE Example 
GO 

SELECT TOP 10 

CP.Reference, 
MAX(C.Surname), 
MAX(C.Email) 

FROM CustomerPackage CP 

INNER JOIN Customer C ON CP.UniqueID = C.UniqueID 
INNER JOIN PurchaseDetails PD ON CP.UniqueID = PD.UniqueID 

WHERE PD.PurchaseDate > dateadd(HOUR,10,getutcdate()) and PD.PurchaseDate < dateadd(DAY,29,getutcdate()) and PD.PurchaseType = 1 
ORDER BY CP.UniqueID DESC 
GROUP BY CP.Reference 
+1

このアプローチは実際には機能しません。なぜなら、最大姓と最大メールは常に同じレコードに対応しない可能性があるからです。とにかく、期待される出力は分の電子メールを意味します。 –

関連する問題