postgresql 如何使一周的开始日用户可配置(一周的第一天,开始日期和结束日期作为一个用户参数)获得周数在Postgres?

eivgtgni  于 2023-01-02  发布在  PostgreSQL
关注(0)|答案(1)|浏览(179)

我想使周的第一天是用户可配置的,因此用户提供周的开始日、开始日期、结束日期作为我现有查询中的用户参数,该查询基于开始日期和结束日期返回周编号(现有查询返回符合ISO的周编号,从星期一(1)开始的日期和结束日星期日(7))。
我在Java代码中使用的周数,用于创建周组(例如:如果开始日期是2022年11月21日&结束日期是2022年11月5日&周开始日是星期三,则预期日期组是2022年11月21日到2022年11月22日、2022年11月23日到2022年12月29日、2022年11月30日到2022年12月5日)。
我应该在现有的查询中更改什么,以便它根据用户提供的开始日期返回确切的周数,开始日期,结束日期作为参数?

select m.tool_id, m.module_location, alarm_count,  recipe_id, alarm_alias, alarm_issuer_name,
DATE_PART('week',alarm_date) AS week, 
DATE_PART('year',alarm_date) AS yearNo
from alarms.alarm_count a, alarms.alarm_module m, alarms.alarm_issuer ai 
where a.module_uuid = m.module_uuid and a.alarm_issuer_uuid = ai.alarm_issuer_uuid 
and m.module_uuid in (
'027909d4-12dd-4b7d-a391-847f88ee97ab',
 '212277f4-9d05-4465-95f7-a99fcb936451')
and (a.alarm_date) BETWEEN '2022-11-21' and '2022-12-05' 
and severity in ('Critical','Error','Fatal')
jq6vz3qz

jq6vz3qz1#

CREATE OR REPLACE FUNCTION test 
( IN start_day text -- must be in ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saterday', 'Sunday')
, IN start_date timestamp
, IN end_date timestamp
, OUT tool_id text -- to be replaced by the real column type
, OUT module_location text -- to be replaced by the real column type
, OUT alarm_count text -- to be replaced by the real column type
, OUT recipe_id text -- to be replaced by the real column type
, OUT alarm_alias text -- to be replaced by the real column type
, OUT alarm_issuer_name text -- to be replaced by the real column type
, OUT week double precision
, OUT yearno double precision
)
  RETURNS setof record LANGUAGE plpgsql AS $$
DECLARE 
  i integer ;
BEGIN
  i := array_position(array['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saterday', 'Sunday'], start_day) ;

  IF i IS NOT NULL 
  THEN
    RETURN QUERY
    select m.tool_id, m.module_location, alarm_count,  recipe_id, alarm_alias, alarm_issuer_name,
    CASE 
         WHEN DATE_PART('week', alarm_date) - (CASE WHEN DATE_PART('isodow', alarm_date) < i THEN 1 ELSE 0 END) :: double precision > 1
         THEN DATE_PART('week', alarm_date) - (CASE WHEN DATE_PART('isodow', alarm_date) < i THEN 1 ELSE 0 END) :: double precision
         ELSE DATE_PART('week', alarm_date - (i-1) * interval '1 days')
    END AS Week,
    CASE 
         WHEN DATE_PART('week', alarm_date) - (CASE WHEN DATE_PART('isodow', alarm_date) < i THEN 1 ELSE 0 END) :: double precision > 1
         THEN DATE_PART('isoyear', alarm_date)
         ELSE DATE_PART('isoyear', alarm_date - (i-1) * interval '1 days')
       END AS YearNo
    from alarms.alarm_count a, alarms.alarm_module m, alarms.alarm_issuer ai 
    where a.module_uuid = m.module_uuid and a.alarm_issuer_uuid = ai.alarm_issuer_uuid 
    and m.module_uuid in (
    '027909d4-12dd-4b7d-a391-847f88ee97ab',
    '212277f4-9d05-4465-95f7-a99fcb936451')
    and (a.alarm_date) BETWEEN '2022-11-21' and '2022-12-05' 
    and severity in ('Critical','Error','Fatal') ;
  END IF ;
END ;
$$ ;

参见dbfiddle

相关问题