我正在使用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 。因此,我需要的答案必须考虑到这一点。
我尝试了这个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
)
我很好奇他们是否也可以通过外部申请来解决,as mentioned in this other SO post
答案 0 :(得分:0)
看起来您需要使用/
来获取最新的ID,但最终的逻辑或对第三个表的需求并不明确。
<强> SQL DEMO 强>
ROW_NUMBER()
<强>输出强>
包含第三个表格:
<强> 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
<强>输出强>
答案 1 :(得分: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
中至少有一条匹配记录,那么IP记录就会通过测试。使用您的数据,所有IP
条记录都会通过测试。
我不确定你到底想要完成什么。如果您每个手机只需要一行,那么我会考虑EXISTS
或IN
。
获得所需结果的最简单方法是:
select p.*
from phones p;
但我怀疑你想要更复杂的逻辑。
答案 2 :(得分: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