我匹配导入Redshift DB的两个数据集:两者都处于rep id级别。
这是我匹配两个数据集的初始查询:
select *
from #t t
join #t2 t2
on lower(trim(t.unique_id))=lower(trim(t2.unique_id))
or lower(trim(t.email))=lower(trim(t2.email))
or lower(trim(split_part(t.first_name,',',1))||trim(split_part(t.last_name,',',1)))=lower(trim(split_part(t2.first_name,',',1))||trim(split_part(t2.last_name,',',1)))
#t
是我匹配的真实来源,unique_id
被认为是rep id(内部标识符)的通用标识符(尽管只匹配约60%),但是,在某些情况下#t2
表每个代表(错误地)多个unique_id
s,并且错误地多个email
s。
如何更改它以使其更具限制性,即。当通过unique_id
获得匹配时 - 不匹配该代表的下一条记录,当匹配email
时 - 不匹配该代表的下一条记录,最后通过名字/姓氏加入。
谢谢!
答案 0 :(得分:1)
我认为有几种方法可以给这只猫上皮。作为一个选项,您可以将每个联接的排名添加为CASE语句,然后选择具有最小排名的那个:
<p>From left to right: name1, name2, name3, name4</p>
您也可以通过查询两次,一次获取数据,一次获得最小值(ranktest)来完成此操作。它几乎肯定会慢一点,但是......它有点漂亮:
SELECT *
FROM
(
SELECT *,
min(ranktest) OVER (PARTITION BY t1.unique_id) as minrank
FROM
(
select *,
CASE WHEN lower(trim(t.unique_id))=lower(trim(t2.unique_id)) THEN 1
WHEN lower(trim(t.email))=lower(trim(t2.email)) THEN 2
WHEN ower(trim(split_part(t.first_name,',',1))||trim(split_part(t.last_name,',',1)))=lower(trim(split_part(t2.first_name,',',1))||trim(split_part(t2.last_name,',',1))) THEN 3
END as ranktest
from #t t
join #t2 t2
on lower(trim(t.unique_id))=lower(trim(t2.unique_id))
or lower(trim(t.email))=lower(trim(t2.email))
or lower(trim(split_part(t.first_name,',',1))||trim(split_part(t.last_name,',',1)))=lower(trim(split_part(t2.first_name,',',1))||trim(split_part(t2.last_name,',',1)))
) sub1
WHERE ranktest = minrank;
或者,您可以将其作为UNION ALL运行,每次都以不同的方式测试连接,以避免重复,并且只允许排名最高的连接:
WITH subquery AS
(
select *,
CASE WHEN lower(trim(t.unique_id))=lower(trim(t2.unique_id)) THEN 1
WHEN lower(trim(t.email))=lower(trim(t2.email)) THEN 2
WHEN ower(trim(split_part(t.first_name,',',1))||trim(split_part(t.last_name,',',1)))=lower(trim(split_part(t2.first_name,',',1))||trim(split_part(t2.last_name,',',1))) THEN 3
END as ranktest
from #t t
join #t2 t2
on lower(trim(t.unique_id))=lower(trim(t2.unique_id))
or lower(trim(t.email))=lower(trim(t2.email))
or lower(trim(split_part(t.first_name,',',1))||trim(split_part(t.last_name,',',1)))=lower(trim(split_part(t2.first_name,',',1))||trim(split_part(t2.last_name,',',1)))
)
SELECT *
FROM subquery t1
WHERE t1.ranktest = (SELECT min(ranktest) FROM subquery WHERE subquery.unique_id = t1.ranktest)