簡體   English   中英

在 window function 中使用 CASE 表達式的結果

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM