簡體   English   中英

T-SQL加入“最大”過濾器

[英]T-SQL Join with “max” filter

我正在使用SQL Server 2014。

我希望以下內容不給我重復的電話ID或號碼:

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,但是我正在使用的實際表使用uniqueidentifier 因此,我需要的答案必須考慮到這一點。

我嘗試了此接受答案的兩個版本,但對我而言不起作用。

我想念什么?

更新

除了我選擇的答案之外,我還意識到解決該問題的另一種方法如下:

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 APPLY解決這些問題, 就像在其他SO帖子中提到的那樣

看起來您需要使用ROW_NUMBER()來獲取最新的ID,但是最終邏輯或對第三張表的需求尚不清楚。

SQL演示

), 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

OUTPUT

在此處輸入圖片說明

包括第三張表:

SQL演示

), 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

在此處輸入圖片說明

我不確定你想要什么。 但是您有這種情況:

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中至少有一條匹配記錄,那么IP記錄就可以通過測試。 有了您的數據,所有IP記錄都通過了測試。

我不確定您實際上要完成什么。 如果每個電話只需要一行,那么我會考慮使用EXISTSIN

獲得所需結果的最簡單方法是:

select p.*
from phones p;

我懷疑您想要更復雜的邏輯。

;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

暫無
暫無

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

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