Sql 如何获取Postgres过去12周的发票数量
发票数据库包含发票日期:Sql 如何获取Postgres过去12周的发票数量,sql,postgresql,asp.net-mvc-3,aggregate-functions,generate-series,Sql,Postgresql,Asp.net Mvc 3,Aggregate Functions,Generate Series,发票数据库包含发票日期: create table dok ( dokumnr serial primary key, invoicedate date not null ); 仪表板需要逗号分隔的列表,其中包含过去12周的发票数量,e.q 4,8,0,6,7,6,0,6,0,4,5,6 列表始终包含12个元素。如果在大约7天的时间间隔内没有发票,则应显示0。 每个元素应包含7天的发票数量 查询应找到当前日期之前的最长日期: select max(invoicedate) as las
create table dok (
dokumnr serial primary key,
invoicedate date not null
);
仪表板需要逗号分隔的列表,其中包含过去12周的发票数量,e.q
4,8,0,6,7,6,0,6,0,4,5,6
列表始终包含12个元素。如果在大约7天的时间间隔内没有发票,则应显示0。
每个元素应包含7天的发票数量
查询应找到当前日期之前的最长日期:
select max(invoicedate) as last_date from dok;
然后可能使用count*和string_agg创建列表
最后12个元素应包含的发票数量
last_date .. last_date-interval'6days'
11最后一项之前的要素应包含发票天数
last_date-interval'7days' .. last_date-interval'14days'
等等
如何在Postgres 9.1+中编写此查询?
这是ASP.NET MVC3 C应用程序,如果有帮助的话,查询的某些部分也可以用C代码完成
我以
with list as (
SELECT count(d.invoicedate) as cnt
FROM (
SELECT max(invoicedate) AS last_date
FROM dok
WHERE invoicedate< current_date
) l
CROSS JOIN generate_series(0, 11*7, 7) AS g(days)
LEFT JOIN dok d ON d.invoicedate> l.last_date - g.days - 7
AND d.invoicedate<= l.last_date - g.days
GROUP BY g.days
ORDER BY g.days desc
)
SELECT string_agg( cnt::text,',')
from list
交叉连接生成_系列的最新日期,然后左连接到主表
SELECT ARRAY(
SELECT count(d.invoicedate) AS ct
FROM (
SELECT max(invoicedate) AS last_date
FROM dok
WHERE invoicedate < current_date -- "maximum date before current date"
) l
CROSS JOIN generate_series(0, 11*7, 7) AS g(days)
LEFT JOIN dok d ON d.invoicedate > l.last_date - g.days - 7
AND d.invoicedate <= l.last_date - g.days
GROUP BY g.days
ORDER BY g.days
);
您的查询已审核:
这是一个实施细节
聚合函数array_agg、json_agg、jsonb_agg、,
json_object_agg、jsonb_object_agg、string_agg和xmlagg,如下所示
以及类似的用户定义聚合函数,生成有意义的
不同的结果值取决于输入值的顺序。
默认情况下,此顺序未指定,但可以由控制
在聚合调用中编写ORDERBY子句,如中所示
. 或者,从
排序的子查询通常会工作。例如:
SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab;
请注意,如果外部查询级别包含
附加处理,例如联接,因为这可能导致
要在计算聚合之前对子查询的输出进行重新排序
我的。
要保持符合标准,您可以编写:
WITH list AS (
SELECT g.days, count(d.invoicedate)::text AS cnt
FROM (
SELECT max(invoicedate) AS last_date
FROM dok
WHERE invoicedate < current_date
) l
CROSS JOIN generate_series(0, 11*7, 7) AS g(days)
LEFT JOIN dok d ON d.invoicedate > l.last_date - g.days - 7
AND d.invoicedate <= l.last_date - g.days
GROUP BY 1
)
SELECT string_agg(cnt, ',' ORDER BY days DESC)
FROM list;
但这有点慢。此外,CTE在技术上不是必需的,而且比子查询慢一点。
SELECT array_to_stringARRAY SELECT…,','像我建议的那样是最快的,因为对于单个结果,数组构造函数比聚合函数字符串快。谢谢。我在问题的更新部分以查询结束。这样行吗?它最近一周会回来吗?安德鲁斯:会的。考虑一下我的答案的补遗。
WITH list AS (
SELECT g.days, count(d.invoicedate)::text AS cnt
FROM (
SELECT max(invoicedate) AS last_date
FROM dok
WHERE invoicedate < current_date
) l
CROSS JOIN generate_series(0, 11*7, 7) AS g(days)
LEFT JOIN dok d ON d.invoicedate > l.last_date - g.days - 7
AND d.invoicedate <= l.last_date - g.days
GROUP BY 1
)
SELECT string_agg(cnt, ',' ORDER BY days DESC)
FROM list;