查询以在PostgreSQL中返回按月计数

时间:2018-12-10 16:31:04

标签: sql postgresql

我正在尝试在PostgreSQL中编写一个查询,当给出两个日期时,该查询应返回“ month”明智的结果。

  SELECT count(overall_sl) as total_sales, count(CASE WHEN overall_sl < value_1 THEN 1 END) failed_sales
    FROM  (
                SELECT overall_sl, value_1
                FROM   salecombined c where c.date_updated between '2018-01-01' and '2018-12-31'
                 GROUP  BY dept_name, date_updated, date, overall_sl, no_addons,  
                value_1, category_id, subcategory_id, branch_name
     ) sales; 

我希望结果是这样的(上面的查询没有做到这一点)

start_dt    end_dt       total_sales   failed_sales
--------    ------       -----------   -------------
2018-01-01  2018-01-31   0              0
2018-02-01  2018-02-28   589            154
2018-03-01  2018-03-31   107            14
2018-04-01  2018-04-30   375            114
-- and so on

我在下面的查询中编写了代码,但执行时间更长;我该如何优化呢?

SELECT  date_trunc('month', dd):: date start_dt,
(date_trunc('month', dd::DATE) + interval '1 month' - interval '1 day')::date as end_dt, 

    (select count(overall_sl) from (
            SELECT overall_sl
        FROM   salecombined c                
        WHERE c.date_updated between date_trunc('month', dd):: date and (date_trunc('month', dd::DATE) + interval '1 month' - interval '1 day')::date
        GROUP  BY dept_name, date_updated, date, overall_sl, no_addons,  
        category_id, subcategory_id, branch_name
         ) jobs
     ) total_sales,

     (select count(CASE WHEN overall_sl < value_1 THEN 1 END) from (
            SELECT overall_sl, value_1
        FROM   salecombined c                
        WHERE c.date_updated between date_trunc('month', dd):: date and (date_trunc('month', dd::DATE) + interval '1 month' - interval '1 day')::date
        GROUP  BY dept_name, date_updated, date, overall_sl, no_addons,  
        value_1, category_id, subcategory_id, branch_name
         ) jobs
     ) failed_sales

FROM generate_series
    ( '2018-01-01'::timestamp 
    , '2018-12-11'::timestamp
    , '1 month'::interval) dd

我不是SQL或PostgreSQL方面的专家。

1 个答案:

答案 0 :(得分:1)

我不确定,但也许您正在搜索GROUP BY date_trunc()

demo:db<>fiddle

SELECT 
    date_trunc('month', sdate)::date as month_begin,
    (date_trunc('month', sdate) + interval '1 month -1 day')::date as month_end,
    SUM(value)
FROM sales    
WHERE sdate BETWEEN <start> and <end>
GROUP BY date_trunc('month', sdate)
  1. date_trunc('month', date)将日期转换为每月的第一天。因此,您可以将一个月内的所有日期分组(因为所有日期都是该月中的第一个月)
  2. date_trunc('month', sdate) + interval '1 month -1 day'计算一个月的最后一天(date_trunc到第一个月,加一个月到下个月的第一天,减去一天到下一个第一天的前一天=最后一天)当前月份。)