这是一个基本的左连接问题,我已经阅读了很多文章,解释了发生了什么,但不知何故,解决方案并没有点击我的脑袋。我左边的桌子有独特的记录。我的右表有左边每条记录的几条记录。
在我读过的文章中,这经常被解释为左表有客户,右表有订单。这非常相似,但不完全是我所面对的。
在我的情况下,左表有唯一的记录,右边有重复的数据要迁移到左表所在的db中。所以我试着编写一个查询,它将加入两者共享的密钥,但我只需要右边的一条记录。我得到的结果当然有多个记录,因为左边的单个左边多次匹配。
我想我需要添加某种过滤功能,例如Top(1)但仍然在阅读/学习,并希望从此列表中的brainiacs获得反馈/指示。
以下是我正在使用的简单架构:
DECLARE @Customer TABLE
(
Id int,
Name varchar(50),
email varchar(50)
)
INSERT @Customer VALUES(1, 'Frodo', 'frodo@middleearth.org')
INSERT @Customer VALUES(2, 'Bilbo', 'Bilbo@middleearth.org')
INSERT @Customer VALUES(3, 'Galadriel', 'Galadriel@middleearth.org')
INSERT @Customer VALUES(4, 'Arwen', 'Arwen@middleearth.org')
INSERT @Customer VALUES(5, 'Gandalf', 'Gandalf@middleearth.org')
DECLARE @CustomerJobs TABLE
(
Id int,
email varchar(50),
jobname varchar(50)
)
INSERT @CustomerJobs VALUES(1, 'frodo@middleearth.org', 'RingBearer')
INSERT @CustomerJobs VALUES(2, 'frodo@middleearth.org', 'RingBearer')
INSERT @CustomerJobs VALUES(3, 'frodo@middleearth.org', 'RingBearer')
INSERT @CustomerJobs VALUES(4, 'frodo@middleearth.org', 'RingBearer')
INSERT @CustomerJobs VALUES(5, 'frodo@middleearth.org', 'RingBearer')
INSERT @CustomerJobs VALUES(6, 'Bilbo@middleearth.org', 'Burglar')
INSERT @CustomerJobs VALUES(7, 'Bilbo@middleearth.org', 'Burglar')
INSERT @CustomerJobs VALUES(8, 'Bilbo@middleearth.org', 'Burglar')
INSERT @CustomerJobs VALUES(9, 'Galadriel@middleearth.org', 'MindReader')
INSERT @CustomerJobs VALUES(10, 'Arwen@middleearth.org', 'Evenstar')
INSERT @CustomerJobs VALUES(10, 'Arwen@middleearth.org', 'Evenstar')
INSERT @CustomerJobs VALUES(11, 'Gandalf@middleearth.org', 'WhiteWizard')
INSERT @CustomerJobs VALUES(12, 'Gandalf@middleearth.org', 'WhiteWizard')
SELECT
Cust.Name,
Cust.email,
CJobs.jobname
FROM
@Customer Cust
LEFT JOIN @CustomerJobs CJobs ON
Cjobs.email = Cust.email
我正在玩row_number over partition(),因为我应该加入一个带有row_number而不是表本身的cte ???
我的另一个约束是我无法从右表中删除重复项。
所以我再次为这个简单化的问题道歉,并感谢你的帮助。
答案 0 :(得分:1)
你必须想出一些人工方法,将每个电子邮件的第二个表减少到一行。例如:
SELECT
Cust.Name,
Cust.ID,
Cust.email,
CJobs.jobname
FROM
@Customer Cust
LEFT JOIN
(select min(id) as id,email, jobname
from
@CustomerJobs
group by email, jobname) as CJobs ON
Cjobs.email = Cust.email
但这几乎是随机的。有没有办法确定CustomerJobs表中哪一行是“正确的”?
答案 1 :(得分:1)
SELECT DISTINCT
Cust.Name,
Cust.email,
CJobs.jobname
FROM
@Customer Cust
LEFT JOIN @CustomerJobs CJobs ON
Cjobs.email = Cust.email
DISTINCT关键字的附加内容可以为您提供所需的内容。
答案 2 :(得分:1)
不使用左连接,而是使用外部应用...然后您可以使用top
子句来限制返回的行...
select
Cust.Name
, Cust.email
, CJobs.jobname
from @Customer Cust
outer apply (
select top 1 *
from @CustomerJobs CJobs
where Cjobs.email = Cust.email
) cjobs;
答案 3 :(得分:1)
这将有效:
SELECT
Cust.Name,
Cust.ID,
Cust.email,
CJobs.jobname
FROM @Customer Cust
LEFT JOIN
(SELECT DISTINCT email, jobname
FROM @CustomerJobs) C2 ON C2.email = C.email