Jay*_*mar 5 sql postgresql select subquery sql-update
我想prod_replay_out根据 Postgres 中的子查询结果更新表。但是,子查询返回多行,但我想跳过这些行并根据子查询返回的单行更新表。
我已经提到链接子查询返回超过 1 行错误,但max()函数不适用于我的预期结果。您能否为我提供一些修改查询的建议?谢谢你。
prod_replay_out 有以下列:
卖家、买家、sender_tag、seller_tag、买家标签、isin、数量、in_msg_time、msg_type、cdsx_time
prod_replay_in 有以下列:
卖家、买家、sender_tag、seller_tag、买家标签、isin、数量、msg_type、cdsx_time
我尝试过什么?
请在下面找到更新sql:
更新sql:
update prod_replay_out O
set in_msg_id =
(Select id
From prod_replay_in I
Where I.msg_type = 'CDST010'
and I.seller = O.seller
and I.buyer = O.buyer
and I.sender_tag = O.sender_tag
and I.seller_tag = O.seller_tag
and I.buyer_tag = O.buyer_tag
and I.isin = O.isin
and I.quantity = O.quantity
and I.cdsx_time = O.in_msg_time
and I.cdsx_time::text like '2020-05-12%'
)
where O.msg_type = 'CDST01C'
and O.cdsx_time::text like '2020-05-12%';
Run Code Online (Sandbox Code Playgroud)
我尝试了以下解决方案。这是正确的方法还是有什么漏洞?
update prod_replay_out O
set in_msg_id =
(Select id
From prod_replay_in I
Where I.msg_type = 'CDST010'
and I.seller = O.seller
and I.buyer = O.buyer
and I.sender_tag = O.sender_tag
and I.seller_tag = O.seller_tag
and I.buyer_tag = O.buyer_tag
and I.isin = O.isin
and I.quantity = O.quantity
and I.cdsx_time = O.in_msg_time
and I.cdsx_time::text like '2020-05-12%'
and 1 = (Select count(id)
From prod_replay_in I
Where I.msg_type = 'CDST010'
and I.seller = O.seller
and I.buyer = O.buyer
and I.sender_tag = O.sender_tag
and I.seller_tag = O.seller_tag
and I.buyer_tag = O.buyer_tag
and I.isin = O.isin
and I.quantity = O.quantity
and I.cdsx_time = O.in_msg_time
and I.cdsx_time::text like '2020-05-12%'
)
)
where O.msg_type = 'CDST01C'
and O.cdsx_time::text like '2020-05-12%';
Run Code Online (Sandbox Code Playgroud)
您只想在子查询返回一行时更新。一种选择是having在子查询中使用聚合和:
update prod_replay_out o
set in_msg_id = (
select max(id)
from prod_replay_in i
where
i.msg_type = 'cdst010'
and i.seller = o.seller
and i.buyer = o.buyer
and i.sender_tag = o.sender_tag
and i.seller_tag = o.seller_tag
and i.buyer_tag = o.buyer_tag
and i.isin = o.isin
and i.quantity = o.quantity
and i.cdsx_time = o.in_msg_time
and i.cdsx_time >= '2020-05-12'::date
and i.cdsx_time < '2020-05-13'::date
having count(*) = 1
)
where
o.msg_type = 'cdst01c'
and o.cdsx_time >= '2020-05-12'::date
and o.cdsx_time < '2020-05-13'::date
Run Code Online (Sandbox Code Playgroud)
请注意,我重写了日期过滤器,以避免转换为文本(您可以使用带有日期文字的半开区间,这样效率更高)。
请注意,这会更新in_msg_id到null子查询返回多行(或根本没有行)的情况。如果你想避免这种情况,你可以在where子句中进行过滤:
update prod_replay_out o
set in_msg_id = (
select max(id)
from prod_replay_in i
where
i.msg_type = 'cdst010'
and i.seller = o.seller
and i.buyer = o.buyer
and i.sender_tag = o.sender_tag
and i.seller_tag = o.seller_tag
and i.buyer_tag = o.buyer_tag
and i.isin = o.isin
and i.quantity = o.quantity
and i.cdsx_time = o.in_msg_time
and i.cdsx_time >= '2020-05-12'::date
and i.cdsx_time < '2020-05-13'::date
having count(*) = 1
)
where
o.msg_type = 'cdst01c'
and o.cdsx_time >= '2020-05-12'::date
and o.cdsx_time < '2020-05-13'::date
and (
select count(*)
from prod_replay_in i
where
i.msg_type = 'cdst010'
and i.seller = o.seller
and i.buyer = o.buyer
and i.sender_tag = o.sender_tag
and i.seller_tag = o.seller_tag
and i.buyer_tag = o.buyer_tag
and i.isin = o.isin
and i.quantity = o.quantity
and i.cdsx_time = o.in_msg_time
and i.cdsx_time >= '2020-05-12'::date
and i.cdsx_time < '2020-05-13'::date
) = 1
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
305 次 |
| 最近记录: |