Informix 的 SQL 查询以获取上个月的所有记录
Posted
技术标签:
【中文标题】Informix 的 SQL 查询以获取上个月的所有记录【英文标题】:SQL query for Informix to get all the records from previous month 【发布时间】:2016-08-17 17:53:03 【问题描述】:我需要一个可以生成上个月生成的记录总数的查询。 我从这个查询开始:
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
但我需要一个查询,它可以动态计算上个月的记录数,而无需对日期进行硬编码。我尝试了很多查询,例如:
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())
但是直到现在我还没有成功。有人可以建议一种使用 Informix SQL 方言获取上个月总记录的方法吗?
【问题讨论】:
您使用的是什么版本的 SQL Server? 我正在使用 Informix。 【参考方案1】:背景
您可以使用 Informix 函数 TODAY
、MONTH()
、YEAR()
和 MDY()
来做到这一点 — 以及一些小技巧。
本月第一天的表达式为:
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)
也会生成“月中日期无效”错误。
回答
所以对于题中的问题,你想要的日期范围是:
SELECT *
FROM taxes
WHERE effect_date >= (MDY(MONTH(TODAY), 1, YEAR(TODAY)) - 1 UNITS MONTH)
AND effect_date < MDY(MONTH(TODAY), 1, YEAR(TODAY))
使用“在本月的第一天之前”比使用“在上个月的最后一天或之前”更容易。但是你可以写:
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_month
和first_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='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;
输出:
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()
【讨论】:
【参考方案2】:几年前,但我认为这仍然是相关信息:
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))
【讨论】:
除了我会使用 TODAY 而不是 CURRENT,...与您几乎在同一时间提出的相同答案。 (我的答案上的创建日期具有误导性;我不小心提交了大约 2 行文本作为答案,所以我将其删除并在删除状态下对其进行了编辑。) @Jonathan Whew!我只是在点击提交后才看到你的,但我很确定它以前不存在。我不知道任何 Informix,所以你必须告诉我为什么这样更好。 CURRENT 是 CURRENT YEAR TO FRACTION(3) 的缩写,因此它生成的是 DATETIME 值而不是 DATE,然后将其转换为 DATE。内部表示完全不同; DATE 是整数类型,第 1 天为 1900-01-01,但 DATETIME 基于 DECIMAL 类型。它们很容易相互转换,但 CURRENT 所涉及的工作比 TODAY 略多。但我忽略了这一点,因为- 1 UNITS MONTH
表示法使用 DATETIME(和 INTERVAL)类型,所以在我使用的代码中也存在 DATE 和 DATETIME 之间的转换并返回到 DATE。
在 Informix 中,TODAY - 1
是昨天,这很有用,但不一定立即显而易见。所有系统在处理日期时都会变得相当冗长——看看其他答案吧。【参考方案3】:
我已经准备好了,因为 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))
如果您从
【讨论】:
【参考方案4】:这应该可以在 MSSQL 中使用:
SELECT COUNT(*)
FROM taxes
WHERE effect_date >= DATEADD(MONTH, -1, effect_date)
我对 Informix 不太熟悉,但语法应该不会太远。
【讨论】:
这在 mssq 或我知道的任何 rdbms 中无效! DATEADD() 不接受 2 个日期作为参数 以上示例使用了 3 个参数:effect_date、-1 和 GETDATE() 表示当前日期。 哇是的,它使用了 3 个参数,但它不是无效的!阅读文档。第一个参数是日期部分,例如日、月、年,第二个是间隔,第三个是要修改的日期。 effect_date 是 datetime 数据类型的列,它不是 datepart。这远非有效,应该删除这个答案! 我编辑了答案 - 现在它是有效的。我只是把它弄混了。 effect_date 是他想要比较的日期。 是的,它现在是一个有效的声明,但不适用于我所知道的任何情况,因为它永远是正确的,effect_date 永远是> = 1个月前。如果他想要上个月当天的所有内容,则 GETDATE() 将是合适的。但是看到现在是八月,他要求从七月开始的一切。以上是关于Informix 的 SQL 查询以获取上个月的所有记录的主要内容,如果未能解决你的问题,请参考以下文章