SQL查询Informix以获取上个月的所有记录

时间:2016-08-17 17:53:04

标签: sql informix

我需要一个查询,它可以生成上个月生成的记录总数。 我从这个问题开始:

SELECT * FROM taxes 
WHERE effect_date >= DATEADD(day,-30, getdate()) 
and effect_date <= getdate()

但是我需要一个查询,它可以动态计算前一个月的记录数,而无需对日期进行硬编码。我尝试过很多查询:

SELECT * 
FROM taxes
WHERE effect_date >= DATEADD(effect_date, -1, GETDATE()) 

node_modules

但直到现在我都没有成功。有人可以建议使用Informix方言SQL来获取上个月的总记录吗?

4 个答案:

答案 0 :(得分:5)

背景

您可以使用Informix函数TODAYMONTH()YEAR()MDY()以及一点点jiggery-pokery来完成。

本月第一天的表达是:

MDY(MONTH(TODAY), 1, YEAR(TODAY))

因此,上个月第一天的表达是:

MDY(MONTH(TODAY), 1, YEAR(TODAY)) - 1 UNITS MONTH

这些表达的优点是它们是明确可靠的;他们不依赖于任何特殊的东西(在您编写的SQL中)来查找该月的最后一天。您可以通过从下个月的第一天减去1 UNITS DAY来查找该月的最后一天。使用现代版本的Informix,您可以进行舍入到月末的日期算术:

SELECT MDY(1,31,2016) + 1 UNITS MONTH FROM sysmaster:'informix'.sysdual;
2016-02-29

但旧版本的Informix会生成错误。即使是现在,MDY(2,31,2016)也会在一个月内产生无效的日期&#39;错误。

答案

因此,对于问题中的问题,您想要的日期范围是:

SELECT *
  FROM taxes
 WHERE effect_date >= (MDY(MONTH(TODAY), 1, YEAR(TODAY)) - 1 UNITS MONTH)
   AND effect_date <   MDY(MONTH(TODAY), 1, YEAR(TODAY))

在本月的第一天之前使用起来更容易&#39;而不是在上个月的最后一天或之前使用&#39;但是你可以写:

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)

或等同于:

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)

使用存储过程

您可以使用任何选定的日期来代替TODAY来概括代码,如果您认为它们过于模糊,您可以编写一个或两个简单的存储过程来执行这些计算。可能的名称包括first_day_this_monthfirst_day_prev_month,将参考日期作为参数传递,默认为今天:

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;

使用示例(假设您的环境中有DBDATE =&#39; Y4MD - &#39;或等效物,因此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;

输出:

aug_1        jul_1        dec_1        sep_1
2016-08-01   2016-07-01   2015-12-01   2015-09-01

因此:

SELECT *
  FROM taxes
 WHERE effect_date >= first_day_prev_month()
   AND effect_date <  first_day_this_month()

答案 1 :(得分:3)

几岁但我认为这仍然是相关信息:

effect_date >=
    MDY(month(current - 1 units month), 1, year(current - 1 units month))
and effect_date < 
    MDY(month(current), 1, year(current))

http://www.dbforums.com/showthread.php?1627297-Informix-query-to-find-first-date-of-previous-month

当然,如果您有一个随机日期,并且您需要从头到尾覆盖它,那么模式类似:

effect_date >=
    MDY(month(<given_date>), 1, year(<given_date>))
and effect_date <
    MDY(month(<given_date> + 1 units month), 1, year(<given_date> + 1 units month))

答案 2 :(得分:0)

这应该在MSSQL中起作用:

SELECT COUNT(*) 
FROM taxes
WHERE effect_date >= DATEADD(MONTH, -1, effect_date) 

我对Informix不太熟悉,但语法不应该太远。

答案 3 :(得分:0)

我已经做好了准备,因为sql-server被标记了你可以将它翻译成informix,也许我也会查找它。

SELECT *
FROM
    taxes
WHERE
    effect_date >= DATEFROMPARTS(YEAR(DATEADD(MONTH,-1,GETDATE())),MONTH(DATEADD(MONTH,-1,GETDATE())),1)
    AND effect_date < DATEFROMPARTS(YEAR(GETDATE()),MONTH(GETDATE()),1)

我认为infomix可能只是:

SELECT *
FROM
    taxes
WHERE
    effect_date >= MDY(MONTH(ADD_MONTHS(CURRENT,-1)),1,YEAR(ADD_MONTHS(CURRENT,-1)))
    AND effect_date < MDY(MONTH(CURRENT),1,YEAR(CURRENT))

如果您从&lt; =更改为&lt;那么你真的不必在上个月末搜索,而是在本月初开始搜索。如果你的effect_date包含时间实际上是你想要的,因为午夜问题。