我想知道除了使用date_trunc使用默认选项之外是否可以截断日期。例如,如果我有一个看起来像这样的表
date dollars
2016-10-03 1
2016-10-05 1
2016-10-10 1
2016-10-17 2
2016-10-24 2
并说我想在每个“双周”期间截断和分组(所以在这个例子中,两个时间段,一个从2016-10-03开始,另一个从2016-10-17开始)。
我希望结果是
date dollars
2016-10-03 3
2016-10-17 4
我该怎么做?我知道date_trunc
我可以做date_trunc('week', date)
之类的事情,但如果我想每两周做一次怎么办?或者如果我想使用其他自定义日期范围怎么办?
答案 0 :(得分:5)
我相信无法仅使用一个内置函数来执行此操作。但是,有多种方法可以将它们结合使用。
要输出与您请求相同的结果,可以使用以下查询:
SELECT TO_DATE(
CONCAT(
DATE_PART('YEAR', date),
(DATE_PART('WEEK', date)::INTEGER / 2) * 2),
'iyyyiw') AS "date",
SUM(dollars) AS dollars
FROM my_table
GROUP BY 1
ORDER BY 1
让我解释一下。 DATE_PART
将从您的日期列中提取星期数(日期从2016-10-03
到2016-10-09
的值为40
,日期从2016-10-10
到{{1 }}的值为2016-10-16
,依此类推。)将其强制转换为41
然后除以INTEGER
将强制执行整数除法,并截断值({2
将保留为20
,20
将截断为{ {1}}等。保留这个截断的数字没有用,因此我将其乘以2以返回要分组的星期数。
我再次使用20.5
从您的20
列中检索年份,然后使用DATE_PART
函数将年份和星期数连接起来,最后使用{{1 }}函数将包含年和周编号的字符串转换为日期格式(使用ISO标准)。
使用此新列将根据需要对数据进行分组。
尽管如此,仅由于您的数据从特定日期date
开始,该日期具有一周的CONCAT
,因此上述解决方案将按预期运行。让我研究另一个可以更好地推广其他日期范围的解决方案。
让我们假设您不希望根据从TO_DATE
开始的两周分组,而希望按照2016-10-03
开始的两周分组(前一周)。您可以使用与上述相同的解决方案,但必须稍加修改。
40
在提取星期时使用函数2016-10-03
之后立即添加2016-09-26
,会将所有星期“移动”到下一个“ bin”(星期SELECT TO_DATE(
CONCAT(
DATE_PART('YEAR', date),
((DATE_PART('WEEK', date) + 1)::INTEGER / 2) * 2 - 1),
'iyyyiw') AS "date",
SUM(dollars) AS dollars
FROM my_table
GROUP BY 1
ORDER BY 1
移至{{1 }},第+1
周移至DATE_PART
等。当然,然后您必须拿走40
才能返回到“原始”容器。但是,这将导致41
除法开始以不同的方式截断所有内容,并且您的查询现在开始按41
开始的两周分组数据。
回答您的问题
或者如果我想使用其他自定义日期范围怎么办?
上述解决方案可以很好地推广到其他情况,例如按三周,两个月分组等。
要开始按其他单位(天,周,月等)进行分组,只需将42
函数更改为+1
,然后将参数2
更改为{{1 }}(在documentation中进行了描述)。您可以使用相同的技巧,使用2016-09-26
和DATE_PART('WEEK',...)
从1月或2月开始对两个月进行分组。
例如,如果您希望按三周分组,则必须将数字除以DATE_PART('MONTH',...)
乘以iyyyiw
。在这里,如果您希望更改分组的前三周时间,则需要使用相同的技巧来添加iyyyim
和+1
,但是现在可能需要使用{{1} }和-1
。
答案 1 :(得分:1)
如果您可以显示“每两周一次的期间号”,而不是显示该期间的开始日期,则可以执行以下操作:
SELECT
FLOOR(EXTRACT(WEEK FROM dt) / 2) AS period,
SUM(dollars) AS dollars
FROM t
GROUP BY FLOOR(EXTRACT(WEEK FROM dt) / 2)
ORDER BY FLOOR(EXTRACT(WEEK FROM dt) / 2)
哪个会给您这些结果:
period dollars
20 3
21 4
在这种情况下,“期间”只是该期间的起始周的ISO周数除以2。您可以对其他范围执行类似的操作。这种方法的问题在于它与日期无关,而与ISO周号有关。