我查询Postgres数据库以获取最近4年的统计数据
但是,我无法找出替换硬编码日期的正确语法
在带有函数的查询的AS
部分中。
说:date_part('year',current_date)-1
而不是"2012"
SELECT * FROM crosstab('
SELECT client,date_part (''year'',date) as SalesDate
,Sum(total)::integer AS Synthese
FROM statistic
WHERE date_part(''year'',date)>date_part(''year'',current_date)-5
AND date_part(''year'',date)<date_part(''year'',current_date)
GROUP BY client,SalesDate
ORDER BY 1,2',
$$VALUES
(date_part('year',current_date)-4),
(date_part('year',current_date)-3),
(date_part('year',current_date)-2),
(date_part('year',current_date)-1)$$)
AS ( client text, "2009" text, "2010" text , "2011" text, "2012" text);
答案 0 :(得分:1)
SQL原则:您可以动态提供 值 ,但 标识符 是静态的。
外部调用是一个基本的SQL语句,列定义列表由标识符组成,而不是值。 (这就是为什么你被迫从一个数字开始双重引用你的非法标识符。)因此,你不能在这个地方使用函数调用。只是不可能。
这方面有一些棘手的方法.. 您可以创建一个plpgsql函数,该函数返回polymorphic composite type并传递一个定义良好的复合类型的参数,该参数也带有列名。但那是非常先进的东西。你需要快速掌握plpgsql。
在这个相关问题下考虑我的全面答案:
Refactor a PL/pgSQL function to return the output of various SELECT queries
答案的后半部分是给你的。
由于您需要一个定义良好的复合类型,因此在以这种方式调用函数之前必须创建一个类型。或者只创建一个临时表(自动提供类型)。您可以使用DO
语句自动执行此操作,该语句使用动态SQL从当前日期派生列名称...我从未说过它很简单,但它是可能的。
同时,您的crosstab()
查询可以改进:
SELECT * FROM crosstab(
$$
SELECT client
,date_part ('year', date) AS salesdate
,sum(total)::int AS synthese
FROM statistic
WHERE date >= date_trunc('year', now()) - interval '5y'
AND date < date_trunc('year', now())
GROUP BY 1,2
ORDER BY 1,2
$$
,$$VALUES
(date_part('year', now()) - 4)
,(date_part('year', now()) - 3)
,(date_part('year', now()) - 2)
,(date_part('year', now()) - 1)
$$
)
AS (client text
,"2009" text
,"2010" text
,"2011" text
,"2012" text);
WHERE
条件,以便他们可以使用索引
Detailed explanation in this closely related answer. 其余的是品味和风格。