连接两个表并根据条件选择一条记录

问题描述 投票:0回答:1

我有 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 巴特 巴特森 “” “”
  • 由于 John 有两个以“A”开头的地址,但有一个主要地址,因此选择主要地址。
  • Mike 有 3 个地址,没有一个是主地址,所以选择以“A”开头的地址。
  • Tim有两个主要地址,所以我们只选择了第一个。
  • Bart 有两个地址,但不是主地址,没有一个以“A”开头,所以留空。
sql left-join greatest-n-per-group
1个回答
0
投票

如果我没听错,我们可以使用

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
.

中过滤每个组(如果有的话)的最佳匹配
© www.soinside.com 2019 - 2024. All rights reserved.