我有 2 个表(客户和地址)。我需要使用 customer_id 列连接两个表,并且每个客户只输出一个记录,其中地址是主要地址,或者如果不是,那么我应该选择地址名称以字母“A”开头的地址。如果没有一个是真的,那么我需要一个空单元格。 (请注意,客户可能有多个地址,其中一些地址可能以“A”开头,我应该只取一个。)为了更清楚,我将尝试形象化下面的任务。
客户
customer_id | 名字 | 姓氏 |
---|---|---|
1 | 约翰 | 约翰尼 |
2 | 迈克 | 米奇 |
3 | 蒂姆 | 添臣 |
4 | 巴特 | 巴特森 |
地址
地址_id | customer_id | 地址行 | 城市 | 是主要的 |
---|---|---|---|---|
1 | 1 | “地址行” | 多伦多 | 0 |
2 | 1 | “另一个地址” | 芝加哥 | 1 |
3 | 2 | “第六大道。” | 洛杉矶 | 0 |
4 | 2 | “只是一个地址” | 盐湖 | 0 |
5 | 3 | “蒂姆街” | 丹佛 | 1 |
6 | 3 | “另一个蒂姆的广告” | 柏林 | 1 |
7 | 4 | 《华尔街》 | 纽约 | 0 |
8 | 4 | “天街” | 伦敦 | 0 |
9 | 4 | “圣天使海峡” | 罗马 | 0 |
10 | 2 | “另一个麦克的” | 伦敦 | 0 |
最终输出应该是这样的:
输出
customer_id | 名字 | 姓氏 | 地址行 | 城市 |
---|---|---|---|---|
1 | 约翰 | 约翰尼 | “另一个地址” | 芝加哥 |
2 | 迈克 | 米奇 | “另一个麦克的” | 伦敦 |
3 | 蒂姆 | 添臣 | “蒂姆街” | 丹佛 |
4 | 巴特 | 巴特森 | “” | “” |
如果我没听错,我们可以使用
row_number()
进行优先级排序和 left join
:
select c.*, a.address_line, a.city
from customers c
left join (
select a.*,
row_number() over(partition by customer_id order by isPrimary desc, address_id) rn
from addresses a
where isPrimary = 1 or address_line like 'A%'
) a on a.customer_id = c.customer_id and a.rn = 1
过滤器上的子查询主要地址或以 A 开头的地址,并为每个客户端对它们进行排名,优先考虑主要地址。如果客户端没有主地址,也没有以 A 开头的地址,则返回一个空集;如果他有多个匹配地址,这会优先考虑主要地址(如果有的话)。
剩下要做的就是在
left join
.中过滤每个组(如果有的话)的最佳匹配