简体   繁体   English

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

[英]SQL query for Informix to get all the records from previous month

I need a query which can generate the total no of records generated in the previous month. 我需要一个查询,该查询可以生成上个月生成的记录总数。 I started with this query: 我从以下查询开始:

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

But I need a query which can dynamically calculate the no of records for a previous month without hard coding the dates. 但是我需要一个查询,该查询可以动态计算上个月的记录数,而无需对日期进行硬编码。 I tried many queries like: 我尝试了很多查询,例如:

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

and

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

but I have had no success until now. 但是直到现在我还没有成功。 Can someone please suggest a way to get the total records from a previous month using the Informix dialect of SQL? 有人可以建议使用SQL的Informix方言从上个月获取总记录的方法吗?

Background 背景

You can do it with Informix functions TODAY , MONTH() , YEAR() and MDY() — and a little jiggery-pokery. 您可以使用Informix函数TODAYMONTH()YEAR()MDY()以及一些麻烦的扑克来做到这一点。

The expression for the first day of this month is: 本月第一天的表达式是:

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

The expression for the first day of the prior month, therefore, is: 因此,上个月第一天的表达式为:

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

The advantage of these expressions is that they are unambiguous and reliable; 这些表达的优点是它们是明确和可靠的。 they don't depend on anything special (in the SQL you write) to find the last day of the month. 他们不需要依靠任何特殊的方法(在您编写的SQL中)来查找月份的最后一天。 You can find the last day of the month by subtracting 1 UNITS DAY from the first day of the following month. 您可以通过从下个月的第一天减去1 UNITS DAY天来找到该月的最后一天。 With modern versions of Informix, you can do date arithmetic that rounds to the end of month: 使用现代版本的Informix,您可以进行日期算术四舍五入到月底:

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

but older versions of Informix would generate an error instead. 但是较旧版本的Informix会生成错误。 Even now, MDY(2,31,2016) generates an 'invalid day in month' error. 即使现在, MDY(2,31,2016)生成“无效的月份”错误。

Answer 回答

So for the problem in the question, the date range you want is: 因此,对于问题中的问题,您想要的日期范围是:

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

It is easier to use 'before the first day of this month' than to use 'on or before the last day of the previous month'. 比“上个月最后一天或之前”使用“本月第一天之前”更容易。 However you could write: 但是,您可以这样写:

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)

or, equivalently: 或等效地:

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)

Using stored procedures 使用存储过程

You could generalize the code by using any chosen date in place of TODAY , and you could write one or two simple stored procedures to do those calculations if you think they're too obscure as shown. 您可以使用任何选择的日期代替TODAY来泛化代码,并且如果您认为如图所示太模糊,可以编写一个或两个简单的存储过程来进行这些计算。 Possible names would include first_day_this_month and first_day_prev_month , passing the reference date as an argument, defaulting to TODAY: 可能的名称包括first_day_this_monthfirst_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;

Example use (assuming you have DBDATE='Y4MD-' or equivalent in your environment, so DATE strings look like ISO 8601 or DATETIME strings): 用法示例(假设您的环境中具有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;

Output: 输出:

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

And hence: 因此:

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

A few years old but I assume this is still relevant info: 几年了,但我认为这仍然是相关信息:

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 http://www.dbforums.com/showthread.php?1627297-Informix-query-to-find-first-date-of-previous-month月

Of course if you were given a random date and you need to cover it's month from the first to the end, the pattern is similar: 当然,如果给了您一个随机的日期,并且您需要从头到尾都覆盖它的月份,则模式类似:

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))

This should work in MSSQL: 这应该在MSSQL中起作用:

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

I'm not too familiar with Informix, but the syntax shouldn't be too far off. 我对Informix不太熟悉,但是语法应该相距不远。

well I had this prepared because sql-server was tagged you can translate the it to informix maybe I will look it up too. 好吧,我已经准备好了,因为sql-server被标记了,您可以将其转换为notifyix,也许我也会查找它。

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)

I think infomix might just be: 我认为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))

If you change from <= to < then you really don't have to search by end of last month but rather than beginning of this month. 如果您从<=更改为<,那么您实际上不必在上个月底之前进行搜索,而不必在本月初进行搜索。 Which if you effect_date has time included would actually be what you want because of the midnight issue. 由于午夜问题,如果您effect_date包含时间,那实际上就是您想要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM