如何将带有多个“on 条件”的左连接的查询转换为 postgres 中的视图?

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

考虑下面的查询(为了简洁起见,这是一个很小的例子)

select * from users u
left join orders o on (u.oid = o.id and o.state='CA') -- 'CA' aka state code will be passed dynamically
where u.id in (1,2,3)

如何将此查询转换为视图?在我的java代码中,当前的userIds和状态是动态的。这意味着对于每个请求,我都会获得一组不同的 userId 和状态,然后我将形成上述查询来获取结果。

但出于性能/其他原因,我想将此查询转换为物化视图或至少转换为普通视图。

主要问题是状态是在“on”状态下传递的。如果这不是动态的,那么查询就会像这样

select * from users u
left join orders o on (u.oid = o.id) -- if state code filter wasn't present/required at all in business requirements
where u.id in (1,2,3)

然后这可以很容易地转换为视图,我可以运行查询

select * from my_custom_view where user_id in (1,2,3)

但是,由于状态是在“on”条件下动态传递的,所以我不确定如何将其转换为视图(既用于组织,也用于稍后通过物化视图等实现性能目的)。

sql postgresql view materialized-views
1个回答
0
投票

本质上,您想要查询和过滤视图(因为它可能预处理数据)并且该视图具有外连接。

如果您没有使用视图,您的“简单查询”将如下所示:

select u.*, o.id as xid, o.state, o.price
from users u
left join orders o on u.oid = o.id and state = 'CA'
where u.id in (1, 2, 3);

删除额外的谓词

state = 'CA'
视图创建为:

create view v as
select u.id as user_id, u.oid as order_id, o.state as state from users u
left join orders o on (u.oid = o.id)
where u.id in (10)
union all
select u.id as user_id, u.oid as order_id, null from users u
where u.id in (10)

要查询此视图并获得相同的结果,您需要考虑外连接。您不需要向其添加谓词

state = 'CA'
,而是需要向其添加谓词
state = 'CA' or state is null

这次,“通过视图查询”将采用以下形式:

select * from v where state = 'CA' or state is null;

您可以看到这两个选项(普通查询和通过视图查询)根据左连接产生相同的结果。

请参阅DB fiddle的运行示例。

© www.soinside.com 2019 - 2024. All rights reserved.