[英]Use the result of CASE expression in window function
以下 SQL 腳本生成 2022 年日歷,其中包含每個日歷間隔的月份、季度、半年和天數:
with clndr as
(
select
gs_day::date
from
generate_series('2022-01-01'::timestamp, current_timestamp, '1 day') as gs_day
),
draft as
(
select
gs_day::date as gs_day
,count(*) over() as full_year_days_cnt
,date_trunc( 'month', gs_day)::date as mnth
,count(*) over(partition by to_char(gs_day::date , 'MM')) as full_month_days_cnt
,case
when to_char(gs_day::date , 'MM') in ('01', '02', '03') then 1
when to_char(gs_day::date , 'MM') in ('04', '05', '06') then 2
when to_char(gs_day::date , 'MM') in ('07', '08', '09') then 3
when to_char(gs_day::date , 'MM') in ('10', '11', '12') then 4
end as year_quarter
,case
when to_char(gs_day::date, 'MM') in ('01', '02', '03', '04', '05', '06') then 1
when to_char(gs_day::date, 'MM') in ('07', '08', '09', '10', '11', '12') then 2
else null
end as year_half
from
generate_series('2022-01-01'::timestamp, current_timestamp, '1 day') as gs_day
)
select
gs_day
,full_year_days_cnt
,mnth
,full_month_days_cnt
,year_quarter
,count(*) over(partition by year_quarter) as year_quarter_days_cnt
,year_half
,count(*) over(partition by year_half) as year_half_days_cnt
from
draft
不幸的是,我必須使用 cte "draft" 來計算 "year_quarter_days_cnt" 和 "year_half_days_cnt",因為我沒有找到任何方法來引用 draft cte 的 select 聲明中的 "year_quarter" 和 "year_half" 別名。
是否有可能避免 cte 或連接使用計數 window function 獲得相同的結果?
您不能在同一個SELECT
列表中引用列別名(“輸出”列名),只能引用輸入列名。 因此,您將在 window function 中重復(再次拼寫) CASE
語句以避免子查詢或 CTE。
幸運的是,您似乎不需要這些復雜的CASE
表達式來開始......
SELECT d::date AS the_day
, count(*) OVER (PARTITION BY extract('year' FROM d)) AS full_year_days_cnt
, date_trunc('month', d)::date AS month
, count(*) OVER (PARTITION BY date_trunc('month', d)) AS full_month_days_cnt
, extract('quarter' FROM d)::int AS year_quarter
, count(*) OVER (PARTITION BY extract('year' FROM d), extract('quarter' FROM d)) AS year_quarter_days_cnt
,(extract('quarter' FROM d)::int + 1) / 2 AS year_half
, count(*) OVER (PARTITION BY extract('year' FROM d), (extract('quarter' FROM d)::int + 1) / 2) AS year_half_days_cnt
FROM generate_series('2022-01-01'::timestamp, LOCALTIMESTAMP, '1 day') d
這也適用於任何給定的開始日期,可以選擇跨越多年——而不是你原來的。
您領先的 CTE clndr
是空運費。
可以根據要求優化 CTE draft
。
我還簡化和/或改進了 rest。
您也可以使用(PARTITION BY to_char(d, 'YYYY-Q'))
代替(PARTITION BY extract('year' FROM d), extract('quarter' FROM d)
)。但是year_half_days_cnt
沒有等效的簡化。
我還將CURRENT_TIMESTAMP
替換為LOCALTIMESTAMP
以避免先驗地涉及timestamptz
。 更干凈,更快。 看:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.