将通过左连接添加的列的值复制到前面1行和后面2行。

huangapple go评论45阅读模式
英文:

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

dbfiddle演示

英文:

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

dbfiddle demo

huangapple
  • 本文由 发表于 2023年4月20日 01:13:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76057196.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定