Postgresql

Postgresql日期函式以可讀格式返回範圍

  • July 25, 2019

我想知道是否可以使用 postgresql 的 date-time 、 concat 和 case 函式來給出以下結果之一:

  • 2019 年 6 月 4 日至 11 日(第 1 天和第 2 天在同一個月內
  • 2019 年 7 月 27 日至 7 月 3 日(第 1 天和第 2 天在不同的日曆月,但在同一日曆年
  • 2019 年 12 月 29 日至 2020 年 1 月 4 日(其中第 1 天和第 2 天在不同的日曆月和不同的年份

我打算創建一個視圖,用於在每週提示更改時發布狀態更新(例如到 Twitter)。在我的程式中,我盡量使用數據庫的原生函式。在一個理想的世界裡,我不會使用原始碼來完成這個,前提是 postgresql 本身能夠做到這一點。

到目前為止,我創建的 VIEW 的 SELECT 查詢是:

SELECT 'chronic pain'::text AS section,
   'https://rons-home.net/en/living-life-lab/tips/living-with-chronic-pain'::text AS link,
   tips_chronic_pain.reference,
   tips_chronic_pain.tip,
   tips_chronic_pain_weekly_selection.start_date,
   tips_chronic_pain_weekly_selection.end_date
FROM tips_chronic_pain
JOIN tips_chronic_pain_weekly_selection ON tips_chronic_pain.reference = tips_chronic_pain_weekly_selection.tips_chronic_pain_reference
ORDER BY tips_chronic_pain_weekly_selection.start_date DESC
LIMIT 1

我創建了以下 2 個表:

表 #1 包含所有提示:

CREATE TABLE public.tips_chronic_pain
(
 reference bigint NOT NULL DEFAULT nextval('tips_chronic_pain_reference_seq'::regclass),
 tip text,
 add_date timestamp with time zone DEFAULT now(), -- UTC
 membership_reference bigint,
 CONSTRAINT tips_chronic_pain_pkey PRIMARY KEY (reference)
)

表 #2 確定目前正在顯示哪個提示:

CREATE TABLE public.tips_chronic_pain_weekly_selection
(
 reference bigint NOT NULL DEFAULT nextval('tips_chronic_pain_weekly_selection_reference_seq'::regclass),
 tips_chronic_pain_reference bigint,
 start_date timestamp with time zone DEFAULT now(), -- UTC
 end_date timestamp with time zone DEFAULT now(), -- UTC
 CONSTRAINT tips_chronic_pain_weekly_selection_pkey PRIMARY KEY (reference)
)
  • 列tips_chronic_pain_weekly_selection.start_date 提供第一個日期
  • 列tips_chronic_pain_weekly_selection.end_date 提供第二個日期
CREATE OR REPLACE FUNCTION readable_date_range(DATERANGE)
RETURNS TEXT AS $$

 SELECT CASE WHEN to_char(LOWER($1), 'YYYY-MM') = to_char(UPPER($1), 'YYYY-MM')
             THEN to_char(LOWER($1), 'FMMonth FMDDth to ') || to_char(UPPER($1), 'FMDDth YYYY')
             WHEN EXTRACT(year FROM LOWER($1)) = EXTRACT(year FROM UPPER($1))
             THEN to_char(LOWER($1), 'FMMonth FMDDth to ') || to_char(UPPER($1), 'FMMonth FMDDth YYYY')
             ELSE to_char(LOWER($1), 'FMMonth FMDDth YYYY to ') || to_char(UPPER($1), 'FMMonth FMDDth YYYY')
             END;

$$ LANGUAGE SQL STRICT IMMUTABLE;

讓我們看一些輸出:

[[local]:5432] user =# SELECT readable_date_range('[2019-01-01,2019-05-03)');
    readable_date_range     
─────────────────────────────
January 1st to May 3rd 2019
(1 row)

Time: 63.280 ms
[[local]:5432] user =# SELECT readable_date_range('[2019-01-01,2019-01-03)');
  readable_date_range   
─────────────────────────
January 1st to 3rd 2019
(1 row)

Time: 0.668 ms
[[local]:5432] user =# SELECT readable_date_range('[2019-01-01,2022-01-03)');
        readable_date_range          
──────────────────────────────────────
January 1st 2019 to January 3rd 2022
(1 row)

Time: 4.563 ms

您可以很容易地修改它以取兩個值。

引用自:https://dba.stackexchange.com/questions/243748