为每个行添加一个满足句点之间标准的行

时间:2012-08-27 15:10:33

标签: sql database postgresql

我有一个Postgres表,我试图根据一些日期列进行分析。

我基本上试图计算表格中满足此要求的行数,然后按月和年分组。而不是我的查询看起来像这样:

SELECT * FROM $TABLE WHERE date1::date <= '2012-05-31' 
                       and date2::date > '2012-05-31';

它应该能够在我的数据中显示这几个月,这样我每次添加新数据时都不必手动更改月份,因此我可以通过一个查询获取所有内容。

在上面的例子中,我希望将符合条件的行总和分组到2012年和05年。同样,如果我的WHERE子句看起来像这样:

date1::date <= '2012-06-31' and date2::date > '2012-06-31'

我希望将这笔款项分为2012年和06年。

3 个答案:

答案 0 :(得分:1)

这对我来说并不完全清楚:

  

我希望将行总和分组

我将以这种方式解释:您希望列出符合条件的“每月”所有行:

WITH x AS (
    SELECT date_trunc('month', min(date1)) AS start
          ,date_trunc('month', max(date2)) + interval '1 month' AS stop
    FROM   tbl
   )
SELECT to_char(y.mon, 'YYYY-MM') AS mon, t.*
FROM  (
   SELECT generate_series(x.start, x.stop, '1 month') AS mon
   FROM   x
   ) y
LEFT   JOIN tbl t ON t.date1::date <= y.mon 
                 AND t.date2::date >  y.mon   -- why the explicit cast to date?
ORDER  BY y.mon, t.date1, t.date2;

假设date2 >= date1

  1. 计算时间段的下边界和上边框并截断为月份(在上边框添加1以包括最后一行。

  2. 使用generate_series()创建有问题的月份集

  3. 您的表中的
  4. LEFT JOIN行具有声明的标准并按月排序。

  5. 您还可以在此阶段GROUP BY计算汇总数。

答案 1 :(得分:0)

这是推理。首先,创建所有可能日期的列表。然后获取date1的累积数量,直到给定日期。然后在日期之后获取date2的累积数量并减去结果。以下查询使用相关子查询(不是我最喜欢的构造,但在这种情况下很方便)来执行此操作:

select thedate,
       (select count(*) from t where date1::date <= d.thedate) -
       (select count(*) from t where date2::date > d.thedate)
from (select distinct thedate
      from ((select date1::date as thedate from t) union all
            (select date2::date as thedate from t)
           ) d
     ) d

这假设date2发生在date1之后。我的模型是客户的开始和停止日期。如果不是这种情况,查询可能无效。

答案 2 :(得分:-1)

听起来您可以从DATEPART T-SQL方法中受益。如果我理解正确,你可以这样做:

SELECT DATEPART(year, date1) Year, DATEPART(month, date1) Month, SUM(value_col)
FROM $Table
-- WHERE CLAUSE ?
GROUP BY DATEPART(year, date1),
  DATEPART(month, date1)