2017-05-17 1 views
0

「最大」のフィルターで参加し、私は、SQL Serverに2014T-SQLは

を使用している私は私に重複する電話番号のまたは数字を与えないために、次たい:私は理解できない

WITH Phones as 
(
    SELECT * FROM (VALUES 
    (1,'602 600 8000'), 
    (2,'602 600 8001'), 
    (3,'602 600 8002') 
    ) AS Vict_t (Id,Number) 
), InvoicePhones as 
(
    SELECT * FROM (VALUES 
    (10, 1, 100, 'Alpha'), 
    (11, 1, 101, 'Bravo'), 
    (12, 1, 102, 'Charlie'), 
    (13, 2, 103, 'Alpha'), 
    (14, 2, 104, 'Bravo'), 
    (15, 2, 105, 'Charlie'), 
    (16, 3, 106, 'Alpha'), 
    (17, 3, 107, 'Bravo'), 
    (18, 3, 108, 'Charlie') 
    ) as ip_t (Id,PhoneId,VoiceId, Name) 
), Voices as 
(
    SELECT * FROM (VALUES 
    (100, '201701'), 
    (101, '201702'), 
    (102, '201703'), 
    (103, '201704'), 
    (104, '201705'), 
    (105, '201706'), 
    (106, '201708'), 
    (107, '201709'), 
    (108, '201710') 
    ) AS Voices_t (Id,BillingCycle) 
) 

SELECT P.Id PhoneId, P.Number, IP.Name 
FROM Phones P 
LEFT JOIN InvoicePhones IP on IP.PhoneId = P.Id and IP.VoiceId = 
    (
    select TOP 1 id 
    from Voices V 
    where V.Id = IP.VoiceId 
    order by V.BillingCycle desc 
    ) 

をサブ選択が重複を排除していない理由私が受けてる何

はこれです:

1 602 600 8000 Alpha 
1 602 600 8000 Bravo 
1 602 600 8000 Charlie 
2 602 600 8001 Alpha 
2 602 600 8001 Bravo 
2 602 600 8001 Charlie 
3 602 600 8002 Alpha 
3 602 600 8002 Bravo 
3 602 600 8002 Charlie 

私は期待していこれは何です:

1 602 600 8000 Charlie 
2 602 600 8001 Charlie 
3 602 600 8002 Charlie 

この例では、単純な整数IDのだが、私が働いている実際のテーブルを使用していますユニーク識別子を使用しています。したがって、私が必要とする答えはそれを考慮する必要があります。

私はこのaccepted answerの両方のバージョンを試しましたが、それは私のためには機能しません。

私には何が欠けていますか?次のように私が選んだ答えに加えて

更新

、私はこの問題を解決するための別の方法を実現している。

SELECT P.Id PhoneId, P.Number, IP.Name 
FROM Phones P 
LEFT JOIN InvoicePhones IP on IP.PhoneId = P.Id and IP.VoiceId = 
    (
    select TOP 1 V.Id 
    from Voices V 
    INNER JOIN InvoicePhones IPS ON IPS.VoiceId = V.Id 
    WHERE P.Id = IPS.PhoneId 
    order by V.BillingCycle desc 
    ) 

、彼らはまた、OUTERを解決することができる場合、私は興味が適用されas mentioned in this other SO post

+0

? –

+2

あなたのサンプルデータはあまり良くありません。なぜなら 'select * from phones'はそれらの結果を得るには十分なものだからです。 –

+0

'サブセレクションが重複を排除していない理由を理解できません。なぜでしょうか?あなたのサブセレクトはあなたが与えたデータで '1と1 = 1'と言ったこととほとんど変わりません。したがって、あなたの全体的なクエリーには違いはありません。 – ZLK

答えて

0

最新のIDを取得するには、ROW_NUMBER()を使用する必要がありますが、最後のロジックや3番目のテーブルの必要性はわかりません。

SQL DEMO

), filter as (
    SELECT P.Id PhoneId, P.Number, IP.Name, IP.VoiceId, 
      ROW_NUMBER() OVER (PARTITION BY P.Id ORDER BY VoiceID DESC) as rn 
    FROM Phones P 
    LEFT JOIN InvoicePhones IP on IP.PhoneId = P.Id 
) 
SELECT * 
FROM filter 
WHERE rn = 1 

第3のテーブルを含むようにOUTPUT

enter image description here

SQL DEMO

), filter as (
    SELECT P.Id PhoneId, P.Number, IP.Name, IP.VoiceId, V.*, 
      ROW_NUMBER() OVER (PARTITION BY P.Id ORDER BY BillingCycle DESC) as rn 
    FROM Phones P 
    LEFT JOIN InvoicePhones IP on IP.PhoneId = P.Id 
    LEFT JOIN Voices V on V.Id = IP.VoiceId 
) 
SELECT * 
FROM filter 
WHERE rn = 1 

OUTPUT

enter image description here

+0

3つのテーブルをすべて結合する必要がある理由を明確にするために質問を更新しました。 –

+0

もう一度EDITバージョンを確認してください –

+0

私が扱っている* real *テーブルには、私が示した整数キーの値の代わりに 'uniqueidentifier'のキータイプがあることを明確にするために質問を更新しました。したがって、私は、キーの順序付け/並べ替えに依存しない答えが必要です。これが第3のテーブルが必要な理由です。 –

0

私はあなたが何をしたいかわかりません。しかし、あなたはこの条件を持っています:

IP.VoiceId = (select TOP 1 id 
       from Voices V 
       where V.Id = IP.VoiceId 
       order by V.BillingCycle desc 
      ) 

相関節はV.id = IP.VoiceIdです。等価比較は本質的にIP.VoiceId = V.idです。彼らは同じです。 Voicesに一致するレコードが少なくとも1つある限り、IPレコードはテストに合格します。あなたのデータでは、すべてのIPレコードがテストに合格します。

本当に達成しようとしていることはわかりません。 1つの電話機につき1つの行だけが必要な場合は、EXISTSまたはINと考えています。

あなたが望む結果を得るための最も簡単な方法は次のとおりです。

select p.* 
from phones p; 

は、私は、しかし、あなたはより洗練されたロジックを望んでいると思われます。

0
;WITH Phones as 
(
    SELECT * FROM (VALUES 
    (1,'602 600 8000'), 
    (2,'602 600 8001'), 
    (3,'602 600 8002') 
    ) AS Vict_t (Id,Number) 
), InvoicePhones as 
(
    SELECT * FROM (VALUES 
    (10, 1, 100, 'Alpha'), 
    (11, 1, 101, 'Bravo'), 
    (12, 1, 102, 'Charlie'), 
    (13, 2, 103, 'Alpha'), 
    (14, 2, 104, 'Bravo'), 
    (15, 2, 105, 'Charlie'), 
    (16, 3, 106, 'Alpha'), 
    (17, 3, 107, 'Bravo'), 
    (18, 3, 108, 'Charlie') 
    ) as ip_t (Id,PhoneId,VoiceId, Name) 
), Voices as 
(
    SELECT * FROM (VALUES 
    (100, '201701'), 
    (101, '201702'), 
    (102, '201703'), 
    (103, '201704'), 
    (104, '201705'), 
    (105, '201706'), 
    (106, '201708'), 
    (107, '201709'), 
    (108, '201710') 
    ) AS Voices_t (Id,BillingCycle) 
) 
,Expected 
AS 
(
SELECT P.Id PhoneId, P.Number, IP.Name 
FROM Phones P 
LEFT JOIN InvoicePhones IP on IP.PhoneId = P.Id and IP.VoiceId = 
    (
    SELECT TOP 1 id 
    FROM Voices V 
    WHERE V.Id = IP.VoiceId 
    ORDER BY V.BillingCycle desc 
    ) 
    ) 
SELECT PhoneId,Number,Name From 
(
SELECT *,ROW_NUMBER()OVER(PARTITION BY Phoneid,Number ORDER BY Phoneid)AS Seq 
FROM Expected 
)DT 
WHERE DT.Seq=3 

出力が期待される結果何

PhoneId Number   Name 
    ------------------------------ 
    1 602 600 8000 Charlie 
    2 602 600 8001 Charlie 
    3 602 600 8002 Charlie