【问题标题】:How to get the count of current month Sunday's in psql?如何在 psql 中获取当前月份星期日的计数?
【发布时间】:2011-02-17 14:56:31
【问题描述】:

如何在 postgresql 中获取给定日期的星期日总数

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    您需要提取物:

    SELECT 
        EXTRACT(DOW FROM DATE '2011-02-16') = 0; -- 0 is Sunday
    

    这可能导致真或假,它是星期天或不是。我不知道你所说的“总数”是什么意思,因为它总是 0(日期不是星期天)或 1(给定的数据是星期天)。

    编辑:像这样?

    SELECT 
        COUNT(*)
    FROM
        generate_series(timestamp '2011-01-01', '2011-03-01', '1 day') AS g(mydate)
    WHERE
        EXTRACT(DOW FROM mydate) = 0;
    

    【讨论】:

    • 他的问题是“如何在 psql 中获取本月星期日的计数?”所以你应该在范围上做一个 count()
    • @Catcall 我在描述上方引用了问题(见标题),我假设“给定日期”是当月的日期。但是,是的,很容易错过:)
    • 你也可以使用 SUM() btw,(我认为,ehrm);-)
    【解决方案2】:

    给定日期的星期日总数只能是 0 或 1。

    但是,如果您想要给定日期范围内的星期日数,那么最好的办法是使用日历表。要知道今年 2 月有多少个星期日,我只需

    select count(*) 
    from calendar
    where cal_date between '2011-02-01' and '2011-02-28' and
          day_of_week = 'Sun';
    

    select count(*)
    from calendar
    where year_of_date = 2011 and
          month_of_year = 2 and 
          day_of_week = 'Sun';
    

    这是您可以开始使用的基本日历表。我还包括一个 PostgreSQL 函数来填充日历表。我没有在 8.3 中测试过,但我很确定我没有使用 8.3 不支持的任何功能。

    请注意,“dow”部分假定您的日子是英文的。但是您可以轻松地编辑这些部分以匹配任何语言。 (我想。但“容易”我可能是错的。)

    -- Table: calendar
    
    -- DROP TABLE calendar;
    
    CREATE TABLE calendar
    (
      cal_date date NOT NULL,
      year_of_date integer NOT NULL,
      month_of_year integer NOT NULL,
      day_of_month integer NOT NULL,
      day_of_week character(3) NOT NULL,
      CONSTRAINT calendar_pkey PRIMARY KEY (cal_date),
      CONSTRAINT calendar_check CHECK (year_of_date::double precision = date_part('year'::text, cal_date)),
      CONSTRAINT calendar_check1 CHECK (month_of_year::double precision = date_part('month'::text, cal_date)),
      CONSTRAINT calendar_check2 CHECK (day_of_month::double precision = date_part('day'::text, cal_date)),
      CONSTRAINT calendar_check3 CHECK (day_of_week::text = 
    CASE
        WHEN date_part('dow'::text, cal_date) = 0::double precision THEN 'Sun'::text
        WHEN date_part('dow'::text, cal_date) = 1::double precision THEN 'Mon'::text
        WHEN date_part('dow'::text, cal_date) = 2::double precision THEN 'Tue'::text
        WHEN date_part('dow'::text, cal_date) = 3::double precision THEN 'Wed'::text
        WHEN date_part('dow'::text, cal_date) = 4::double precision THEN 'Thu'::text
        WHEN date_part('dow'::text, cal_date) = 5::double precision THEN 'Fri'::text
        WHEN date_part('dow'::text, cal_date) = 6::double precision THEN 'Sat'::text
        ELSE NULL::text
    END)
    )
    WITH (
      OIDS=FALSE
    );
    ALTER TABLE calendar OWNER TO postgres;
    
    -- Index: calendar_day_of_month
    
    -- DROP INDEX calendar_day_of_month;
    
    CREATE INDEX calendar_day_of_month
      ON calendar
      USING btree
      (day_of_month);
    
    -- Index: calendar_day_of_week
    
    -- DROP INDEX calendar_day_of_week;
    
    CREATE INDEX calendar_day_of_week
      ON calendar
      USING btree
      (day_of_week);
    
    -- Index: calendar_month_of_year
    
    -- DROP INDEX calendar_month_of_year;
    
    CREATE INDEX calendar_month_of_year
      ON calendar
      USING btree
      (month_of_year);
    
    -- Index: calendar_year_of_date
    
    -- DROP INDEX calendar_year_of_date;
    
    CREATE INDEX calendar_year_of_date
      ON calendar
      USING btree
      (year_of_date);
    

    以及填充表格的基本功能。我也没有在 8.3 中测试过。

    -- Function: insert_range_into_calendar(date, date)
    
    -- DROP FUNCTION insert_range_into_calendar(date, date);
    
    CREATE OR REPLACE FUNCTION insert_range_into_calendar(from_date date, to_date date)
      RETURNS void AS
    $BODY$
    
    DECLARE
        this_date date := from_date;
    BEGIN
    
        while (this_date <= to_date) LOOP
            INSERT INTO calendar (cal_date, year_of_date, month_of_year, day_of_month, day_of_week)
            VALUES (this_date, extract(year from this_date), extract(month from this_date), extract(day from this_date),
            case when extract(dow from this_date) = 0 then 'Sun'
                 when extract(dow from this_date) = 1 then 'Mon'
                 when extract(dow from this_date) = 2 then 'Tue'
                 when extract(dow from this_date) = 3 then 'Wed'
                 when extract(dow from this_date) = 4 then 'Thu'
                 when extract(dow from this_date) = 5 then 'Fri'
                 when extract(dow from this_date) = 6 then 'Sat'
            end);
            this_date = this_date + interval '1 day';
        end loop;       
    
    END;
    $BODY$
      LANGUAGE plpgsql VOLATILE
      COST 100;
    

    【讨论】:

    • 日历表是默认表还是我们需要创建?
    • 我使用的是 PostgreSQL 8.3。我没有日历表
    • 使用 generate_series,看我的回答。
    • @ungalnanban:我发布了创建和填充日历表的代码。
    • @Frank Heikens:日历表更通用——对其进行简单查询可以回答范围广泛的问题。 (“简单”意味着维护程序员和实习生可以在不问我问题的情况下做到这一点。)关于它的查询和视图可以利用索引。使用工作中的典型查询,日历表比 generate_series() 快 2 到 15 倍,并且可以轻松用于连接。日历表也与平台无关——它们甚至可以在 Microsoft Access 中工作。
    猜你喜欢
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    • 2018-12-14
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    相关资源
    最近更新 更多