考虑下面的查询(为了简洁起见,这是一个很小的例子)
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”条件下动态传递的,所以我不确定如何将其转换为视图(既用于组织,也用于稍后通过物化视图等实现性能目的)。
本质上,您想要查询和过滤视图(因为它可能预处理数据)并且该视图具有外连接。
如果您没有使用视图,您的“简单查询”将如下所示:
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的运行示例。