英文:
Copy the value of the column added via left join to the previous 1 row and the following 2 rows
问题
I am trying to copy the value of the column added via left join to the previous 1 row and the following 2 rows.
我正在尝试将通过左连接添加的列的值复制到前1行和后2行。
I created a helper table with numeric yearmonth_IDs for each yearmonth to solve the problem during the join. (yearmonth cannot be used for this purpose because it is not continuous; for instance 202301-1=202300; and this is not returning a valid yearmonth.)
我创建了一个帮助表,其中包含每个年月的数字年月_ID,以在连接过程中解决问题。(年月不能用于此目的,因为它不是连续的;例如,202301-1=202300;这不会返回有效的年月。)
What is an alternative solution using other built-in functions instead of using a helper table/column, as I've done?
有没有其他内置函数的替代解决方案,而不是像我所做的那样使用帮助表/列?
Data:
数据:
drop table if exists public.left_table;
create table public.left_table (contractid integer, yearmonth varchar(6), desired boolean);
insert into public.left_table (contractid, yearmonth, desired)
values
(1, 202201, false), (1, 202202, true), (1, 202203, true), (1, 202204, true), (1, 202205, true), (1, 202206, false), (1, 202207, false),
(2, 202210, false), (2, 202211, false), (2, 202212, true), (2, 202301, true), (2, 202302, true), (2, 202303, true), (2, 202304, false);
select * from left_table;
drop table public.right_table;
create table public.right_table (contractid integer, yearmonth varchar(6), flag boolean);
insert into public.right_table (contractid, yearmonth, flag)
values
(1, 202203, true),
(2, 202301, true);
select * from right_table;
My solution:
我的解决方案:
drop table if exists yearmonth_ids;
create table yearmonth_ids as
select row_number() over() yearmonth_id, to_char(x, 'YYYYMM') yearmonth
from generate_series('2018-01-01', current_date, '1 month') x;
select * from yearmonth_ids;
select
lt.,
coalesce(rt.flag, false) flag
from
(select l., y.yearmonth_id from left_table l left join yearmonth_ids y on l.yearmonth = y.yearmonth) lt
left join
(select r.*, y.yearmonth_id from right_table r left join yearmonth_ids y on r.yearmonth = y.yearmonth) rt
on lt.contractid = rt.contractid and lt.yearmonth_id between rt.yearmonth_id-1 and rt.yearmonth_id+2
order by lt.contractid, lt.yearmonth;
英文:
I am trying to copy the value of the column added via left join to the previous 1 row and the following 2 rows.
I created a helper table with numeric yearmonth_IDs for each yearmonth to solve the problem during the join. (yearmonth cannot be used for this purpose because it is not continious; for instance 202301-1=202300; and this is not returning a valid yearmonth.)
What is an alternative solution using other built-in functions instead of using a helper table/column, as I've done?
Data:
drop table if exists public.left_table;
create table public.left_table (contractid integer, yearmonth varchar(6), desired boolean);
insert into public.left_table (contractid, yearmonth, desired)
values
(1, 202201, false), (1, 202202, true), (1, 202203, true), (1, 202204, true), (1, 202205, true), (1, 202206, false), (1, 202207, false),
(2, 202210, false), (2, 202211, false), (2, 202212, true), (2, 202301, true), (2, 202302, true), (2, 202303, true), (2, 202304, false);
select * from left_table;
drop table public.right_table;
create table public.right_table (contractid integer, yearmonth varchar(6), flag boolean);
insert into public.right_table (contractid, yearmonth, flag)
values
(1, 202203, true),
(2, 202301, true);
select * from right_table;
My solution:
drop table if exists yearmonth_ids;
create table yearmonth_ids as
select row_number() over() yearmonth_id, to_char(x, 'YYYYMM') yearmonth
from generate_series('2018-01-01', current_date, '1 month') x;
select * from yearmonth_ids;
select
lt.*,
coalesce(rt.flag, false) flag
from
(select l.*, y.yearmonth_id from left_table l left join yearmonth_ids y on l.yearmonth = y.yearmonth) lt
left join
(select r.*, y.yearmonth_id from right_table r left join yearmonth_ids y on r.yearmonth = y.yearmonth) rt
on lt.contractid = rt.contractid and lt.yearmonth_id between rt.yearmonth_id-1 and rt.yearmonth_id+2
order by lt.contractid, lt.yearmonth;
答案1
得分: 1
不需要辅助表,您可以像这样操作日期:
select l.contractid, l.yearmonth, l.desired, coalesce(r.flag, false) flag
from left_table l
left join right_table r on to_date(l.yearmonth, 'yyyymm')
between to_date(r.yearmonth, 'yyyymm') - interval '1' month
and to_date(r.yearmonth, 'yyyymm') + interval '2' month
英文:
No need for helper table, you can operate on dates like here:
select l.contractid, l.yearmonth, l.desired, coalesce(r.flag, false) flag
from left_table l
left join right_table r on to_date(l.yearmonth, 'yyyymm')
between to_date(r.yearmonth, 'yyyymm') - interval '1' month
and to_date(r.yearmonth, 'yyyymm') + interval '2' month
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论