postgresql根據查詢日期所在月份的週數查詢去年該月份對應週數的日期
create or replace function get_last_year_day_by_week(in _date timestamp)
returns varchar as $$
declare _this_year_week_date timestamp[]='{}';-- 查詢日期所在月份的所有的_this_date_week的日期
declare _last_year_week_date timestamp[]='{}';-- 查詢日期去年所在月的所有的_this_date_week的日期
declare _date_row record;
declare _date_array_item timestamp;-- 查詢日期所在月份的所有的_this_date_week的日期的某一元素
declare _date_array_length int;-- 查詢日期所在月份的所有的_this_date_week的日期陣列長度
declare _date_array_i int;-- 查詢日期所在月份的所有的_this_date_week的日期陣列index
declare _this_date_month_week_index int;-- 記錄查詢日期是本月的第幾個周_this_date_week**
declare _this_date_last_month_same_week timestamp;-- 記錄查詢日期去年這個月的第幾周_this_date_week日期**
declare _this_date_week int;-- 記錄查詢日期是星期幾**
declare _this_date_year int;-- 記錄查詢日期年
declare _this_date_month int;-- 記錄查詢日期月
declare _this_date_day int;-- 記錄查詢日期日
declare _this_date_first_day timestamp;-- 記錄查詢日期這個月第一天
declare _this_date_last_day timestamp;-- 記錄查詢日期這個月最後一天
declare _this_date_last_year_first_day timestamp;-- 記錄查詢日期去年這個月第一天
declare _this_date_last_year_last_day timestamp;-- 記錄查詢日期去年這個月最後一天
begin
select extract(year from _date),extract(month from _date),extract(day from _date),extract(dow from _date)
into _this_date_year,_this_date_month,_this_date_day,_this_date_week;
if _this_date_month=12 then
_this_date_last_year_first_day=to_timestamp( ''||(_this_date_year-1)||'-12-01','yyyy-MM-dd');
_this_date_last_year_last_day=to_timestamp( ''||(_this_date_year-1)||'-12-31','yyyy-MM-dd') ;
_this_date_first_day=to_timestamp( ''||_this_date_year||'-12-01','yyyy-MM-dd');
_this_date_last_day=to_timestamp( ''||_this_date_year||'-12-31','yyyy-MM-dd');
else
_this_date_last_year_first_day=to_timestamp( ''||(_this_date_year-1)||'-'||_this_date_month||'-01','yyyy-MM-dd');
_this_date_last_year_last_day=to_timestamp( ''||(_this_date_year-1)||'-'||(_this_date_month+1)||'-01','yyyy-MM-dd')+'-1 day';
_this_date_first_day=to_timestamp( ''||_this_date_year||'-'||_this_date_month||'-01','yyyy-MM-dd');
_this_date_last_day=to_timestamp( ''||_this_date_year||'-'||(_this_date_month+1)||'-01','yyyy-MM-dd')+'-1 day';
end if;
-- raise info '_this_date_last_year_first_day:%',_this_date_last_year_first_day;
-- raise info '_this_date_last_year_last_day:%',_this_date_last_year_last_day;
-- raise info '_this_date_first_day:%',_this_date_first_day;
-- raise info '_this_date_last_day:%',_this_date_last_day;
-- raise info '_this_date_week:%',_this_date_week;
for _date_row in select date_val::timestamp
from generate_series(_this_date_first_day,_this_date_last_day,'1 day') date_val
where extract(dow from date_val)=_this_date_week
loop
_this_year_week_date=_this_year_week_date||_date_row.date_val;
-- raise info '%',_date_row.date_val;
end loop;
_date_array_length=array_length(_this_year_week_date,1);
for _date_array_i in 1.._date_array_length loop
if _this_year_week_date[_date_array_i]=_date then
_this_date_month_week_index=_date_array_i;
-- raise info '_date_array_i:%',_date_array_i;
exit;
end if;
end loop;
if _this_date_month_week_index is null then
_this_date_month_week_index=0;
return '';
end if;
-- raise info '%',_this_year_week_date;
for _date_row in select date_val::timestamp
from generate_series(_this_date_last_year_first_day,_this_date_last_year_last_day,'1 day') date_val
where extract(dow from date_val)=_this_date_week
loop
_last_year_week_date=_last_year_week_date||_date_row.date_val;
-- raise info 'last month : %',_date_row.date_val;
end loop;
_date_array_length=array_length(_last_year_week_date,1);
if _date_array_length<_this_date_month_week_index then
return '';
end if;
_this_date_last_month_same_week=_last_year_week_date[_this_date_month_week_index] ;
-- raise info '_this_date_last_month_same_week : %',_this_date_last_month_same_week;
return _this_date_last_month_same_week;
end ;
$$ language plpgsql
;select last_month from get_last_year_day_by_week('2018-7-2'::timestamp) last_month