如果条件满足则选择 A 行,否则为每个组选择 B 行
Posted
技术标签:
【中文标题】如果条件满足则选择 A 行,否则为每个组选择 B 行【英文标题】:Select row A if a condition satisfies else select row B for each group 【发布时间】:2021-10-12 17:43:39 【问题描述】:我们有 2 张桌子、预订和文档
预订
booking_id | name
100 | "Val1"
101 | "Val5"
102 | "Val6"
文档
doc_id | booking_id | doc_type_id
6 | 100 | 1
7 | 100 | 2
8 | 101 | 1
9 | 101 | 2
10 | 101 | 2
我们需要这样的结果:
booking_id | doc_id
100 | 7
101 | 10
本质上,我们正在尝试获取每次预订的最新文档记录,但如果存在 doc_type_id 2,则选择 doc type 2 的最新记录,否则选择 doc_type_id 1 的最新记录。
这是否可以通过性能友好的查询来实现,因为我们需要在非常庞大的查询中应用它?
【问题讨论】:
我使用的是 10.5.4 【参考方案1】:您可以使用FIRST_VALUE()
窗口函数来做到这一点,方法是对每个booking_id
的行进行正确排序,以便首先返回带有doc_type_id = 2
的行:
SELECT DISTINCT booking_id,
FIRST_VALUE(doc_id) OVER (PARTITION BY booking_id ORDER BY doc_type_id = 2 DESC, doc_id DESC) rn
FROM docs;
如果您想返回完整的行,那么您可以使用ROW_NUMBER()
窗口函数:
SELECT booking_id, doc_id, doc_type_id
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY booking_id ORDER BY doc_type_id = 2 DESC, doc_id DESC) rn
FROM docs
) t
WHERE rn = 1;
【讨论】:
我对多个列做了如下操作,这样我就可以避免子查询希望获得性能 SELECT DISTINCT booking_id, FIRST_VALUE(doc_id) OVER (W) doc_id, FIRST_VALUE(doc_type_id) OVER (W) doc_type_id FROM docs WINDOW W AS (PARTITION BY booking_id ORDER BY doc_type_id = 2 DESC, doc_id DESC);以上是关于如果条件满足则选择 A 行,否则为每个组选择 B 行的主要内容,如果未能解决你的问题,请参考以下文章
PHP / SQL:如果在表A和表B中更新后满足条件,则更新表C