首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于Informix的SQL查询,用于获取上个月的所有记录

用于Informix的SQL查询,用于获取上个月的所有记录
EN

Stack Overflow用户
提问于 2016-08-18 01:53:04
回答 4查看 8.3K关注 0票数 2

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

代码语言:javascript
复制
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

但我需要一个查询,可以动态计算前一个月的记录数量,而不是硬编码的日期。我尝试了许多查询,例如:

代码语言:javascript
复制
SELECT * FROM taxes 
WHERE effect_date >= DATEADD(day,-30, getdate()) 
and effect_date <= getdate()

代码语言:javascript
复制
SELECT * 
FROM taxes
WHERE effect_date >= DATEADD(effect_date, -1, GETDATE()) 

但是直到现在我还没有成功。有人能建议一种使用SQL的Informix方言从上个月获得总记录的方法吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-08-18 04:52:53

背景

您可以使用Informix TODAYMONTH()YEAR()MDY() --以及一些小技巧--来完成这项工作。

这个月的第一天的表达式是:

代码语言:javascript
复制
MDY(MONTH(TODAY), 1, YEAR(TODAY))

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

代码语言:javascript
复制
MDY(MONTH(TODAY), 1, YEAR(TODAY)) - 1 UNITS MONTH

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

代码语言:javascript
复制
SELECT MDY(1,31,2016) + 1 UNITS MONTH FROM sysmaster:'informix'.sysdual;
2016-02-29

但是旧版本的Informix会生成错误。即使是现在,MDY(2,31,2016)也会生成一个“无效的月份中的某一天”错误。

答案

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

代码语言:javascript
复制
SELECT *
  FROM taxes
 WHERE effect_date >= (MDY(MONTH(TODAY), 1, YEAR(TODAY)) - 1 UNITS MONTH)
   AND effect_date <   MDY(MONTH(TODAY), 1, YEAR(TODAY))

“在这个月的第一天之前”比“在上个月的最后一天或之前”更容易使用。但是,您可以这样写:

代码语言:javascript
复制
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)

或者,等效地:

代码语言:javascript
复制
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,将引用日期作为参数传递,默认为今天:

代码语言:javascript
复制
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='Y4MD-‘或等效的,因此日期字符串看起来像ISO 8601或DATETIME字符串):

代码语言:javascript
复制
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;

输出:

代码语言:javascript
复制
aug_1        jul_1        dec_1        sep_1
2016-08-01   2016-07-01   2015-12-01   2015-09-01

因此:

代码语言:javascript
复制
SELECT *
  FROM taxes
 WHERE effect_date >= first_day_prev_month()
   AND effect_date <  first_day_this_month()
票数 8
EN

Stack Overflow用户

发布于 2016-08-18 05:30:32

几年前,但我认为这仍然是相关的信息:

代码语言:javascript
复制
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

当然,如果给你一个随机的日期,你需要从头到尾涵盖它的月份,模式是相似的:

代码语言:javascript
复制
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))
票数 3
EN

Stack Overflow用户

发布于 2016-08-18 02:00:41

这在MSSQL中应该是有效的:

代码语言:javascript
复制
SELECT COUNT(*) 
FROM taxes
WHERE effect_date >= DATEADD(MONTH, -1, effect_date) 

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39003297

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档