我有一个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年。
答案 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以包括最后一行。
使用generate_series()
创建有问题的月份集
LEFT JOIN
行具有声明的标准并按月排序。
您还可以在此阶段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)