我需要一个查询,它可以生成上个月生成的记录总数.我从这个查询开始:
select state, taxing_entity, count(taxing_entity) Total_TRXN_Count
from taxes where effect_date between '2016/07/01' and '2016/07/31'
group by state, taxing_entity, effect_date
Run Code Online (Sandbox Code Playgroud)
但我需要一个查询,它可以动态计算前一个月的记录数,而无需对日期进行硬编码.我尝试了很多查询,例如:
SELECT * FROM taxes
WHERE effect_date >= DATEADD(day,-30, getdate())
and effect_date <= getdate()
Run Code Online (Sandbox Code Playgroud)
和
SELECT *
FROM taxes
WHERE effect_date >= DATEADD(effect_date, -1, GETDATE())
Run Code Online (Sandbox Code Playgroud)
但直到现在我还没有成功.有人可以建议一种方法来使用SQL的Informix方言获取上个月的总记录吗?
您可以使用Informix功能做到这一点TODAY,MONTH(),YEAR()和MDY()和一个小暗中捣鬼- .
本月第一天的表达是:
MDY(MONTH(TODAY), 1, YEAR(TODAY))
Run Code Online (Sandbox Code Playgroud)
因此,上个月第一天的表达式是:
MDY(MONTH(TODAY), 1, YEAR(TODAY)) - 1 UNITS MONTH
Run Code Online (Sandbox Code Playgroud)
这些表达的优点是它们是明确和可靠的; 他们不依赖任何特殊的东西(在您编写的SQL中)来查找该月的最后一天.您可以通过1 UNITS DAY从下个月的第一天减去来找到该月的最后一天.使用现代版本的Informix,您可以进行舍入到月末的日期算术:
SELECT MDY(1,31,2016) + 1 UNITS MONTH FROM sysmaster:'informix'.sysdual;
2016-02-29
Run Code Online (Sandbox Code Playgroud)
但旧版本的Informix会生成错误.即使是现在,也会MDY(2,31,2016)生成"每月无效"错误.
因此,对于问题中的问题,您想要的日期范围是:
SELECT *
FROM taxes
WHERE effect_date >= (MDY(MONTH(TODAY), 1, YEAR(TODAY)) - 1 UNITS MONTH)
AND effect_date < MDY(MONTH(TODAY), 1, YEAR(TODAY))
Run Code Online (Sandbox Code Playgroud)
在"本月第一天之前"使用"比在上个月的最后一天或之前使用"更容易.但是你可以写:
SELECT *
FROM taxes
WHERE effect_date >= (MDY(MONTH(TODAY), 1, YEAR(TODAY)) - 1 UNITS MONTH)
AND effect_date <= (MDY(MONTH(TODAY), 1, YEAR(TODAY)) - 1 UNITS DAY)
Run Code Online (Sandbox Code Playgroud)
或者,等效地:
SELECT *
FROM taxes
WHERE effect_date BETWEEN (MDY(MONTH(TODAY), 1, YEAR(TODAY)) - 1 UNITS MONTH)
AND (MDY(MONTH(TODAY), 1, YEAR(TODAY)) - 1 UNITS DAY)
Run Code Online (Sandbox Code Playgroud)
您可以使用任何选择的日期代替来概括代码,TODAY如果您认为它们太模糊,您可以编写一个或两个简单的存储过程来进行这些计算.可能的名称包括first_day_this_month和first_day_prev_month,将引用日期作为参数传递,默认为TODAY:
CREATE PROCEDURE first_day_this_month(refdate DATE DEFAULT TODAY)
RETURNING DATE AS first_day;
RETURN MDY(MONTH(refdate), 1, YEAR(refdate));
END PROCEDURE;
CREATE PROCEDURE first_day_prev_month(refdate DATE DEFAULT TODAY)
RETURNING DATE AS first_day;
RETURN MDY(MONTH(refdate), 1, YEAR(refdate)) - 1 UNITS MONTH;
END PROCEDURE;
Run Code Online (Sandbox Code Playgroud)
使用示例(假设您的环境中有DBDATE ='Y4MD-'或等效项,因此DATE字符串看起来像ISO 8601或DATETIME字符串):
SELECT first_day_this_month() AS aug_1,
first_day_prev_month() AS jul_1,
first_day_this_month(DATE('2015-12-25')) as dec_1,
first_day_prev_month(DATE('2015-10-31')) AS sep_1
FROM sysmaster:'informix'.sysdual;
Run Code Online (Sandbox Code Playgroud)
输出:
aug_1 jul_1 dec_1 sep_1
2016-08-01 2016-07-01 2015-12-01 2015-09-01
Run Code Online (Sandbox Code Playgroud)
因此:
SELECT *
FROM taxes
WHERE effect_date >= first_day_prev_month()
AND effect_date < first_day_this_month()
Run Code Online (Sandbox Code Playgroud)