Sql 如何将函数作为查询的一部分包含在中?
我查询Postgres数据库以获取过去4年的统计数据。Sql 如何将函数作为查询的一部分包含在中?,sql,postgresql,plpgsql,crosstab,Sql,Postgresql,Plpgsql,Crosstab,我查询Postgres数据库以获取过去4年的统计数据。 但是,我无法找出正确的语法来替换硬编码日期 在中,作为带有函数的查询的一部分 说:date\u part('year',current\u date)-1而不是“2012” 从交叉表中选择* 选择客户,日期/零件(“年”,日期)作为SalesDate ,总和(总计)::整数作为合成器 从统计 其中日期部分(“年”,日期)>日期部分(“年”,当前日期)-5 和日期部分(“年”,日期)答案 SQL的一个原则是:可以动态提供值,但标识符是静态的
但是,我无法找出正确的语法来替换硬编码日期 在
中,作为带有函数的查询的一部分
说:date\u part('year',current\u date)-1而不是“2012”
从交叉表中选择*
选择客户,日期/零件(“年”,日期)作为SalesDate
,总和(总计)::整数作为合成器
从统计
其中日期部分(“年”,日期)>日期部分(“年”,当前日期)-5
和日期部分(“年”,日期)答案
SQL的一个原则是:可以动态提供值,但标识符是静态的
外部调用是一个基本SQL语句,列定义列表由标识符组成,而不是值。(这就是为什么您必须双引号引用以数字开头的非法标识符。)因此,您不能在此位置使用函数调用。这是不可能的
可能的解决办法
解决这个问题有很多棘手的办法。。
您可以创建一个plpgsql函数,该函数返回一个值,并提交一个定义良好的复合类型的参数,该类型还包含列名。但这是非常高级的内容。为此,您需要熟悉plpgsql
考虑我在这个相关问题下的综合回答:
答案的后半部分是给你的
由于您需要一个定义良好的复合类型,因此必须在以这种方式调用函数之前创建一个类型,或者只创建一个临时表(自动提供类型)。您可以使用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);
从交叉表中选择*(
$$
选择客户端
,日期/零件('年',日期)作为销售日期
,总和(合计)::整数作为合成数
从统计
其中日期>=日期(“年”,现在())-间隔“5y”
日期
- 使用美元报价以避免引用地狱
- 重写您的
WHERE
条件,以便它们可以使用索引。
剩下的是品味和风格的问题。回答
SQL的一个原则是:可以动态提供值,但标识符是静态的
外部调用是一个基本SQL语句,列定义列表由标识符组成,而不是值。(这就是为什么您必须双引号引用以数字开头的非法标识符。)因此,您不能在此位置使用函数调用。这是不可能的
可能的解决办法
解决这个问题有很多棘手的办法。。
您可以创建一个plpgsql函数,该函数返回一个值,并提交一个定义良好的复合类型的参数,该类型还包含列名。但这是非常高级的内容。为此,您需要熟悉plpgsql
考虑我在这个相关问题下的综合回答:
答案的后半部分是给你的
由于您需要一个定义良好的复合类型,因此必须在以这种方式调用函数之前创建一个类型,或者只创建一个临时表(自动提供类型)。您可以使用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);
从交叉表中选择*(
$$
选择客户端
,日期/零件('年',日期)作为销售日期
,总和(合计)::整数作为合成数
从统计
其中日期>=日期(“年”,现在())-间隔“5y”
日期
- 使用美元报价以避免引用地狱
- 重写您的
WHERE
条件,以便它们可以使用索引。
剩下的是品味和风格的问题。是的,你的文章写得更清楚了——这样高质量的答案对学习来说真是太好了:)-因为将结果导出到一个报告I平面,以便对结果进行后处理,以便轻松修改当前日期标题部分。TksYes您的书写更加清晰-这样的高质量答案对学习非常有用:)-因为将结果导出到一个报告I平面,以便对结果进行后处理,以便轻松修改当前日期标题部分.Tks