每月最后一天加入第二张桌子

Posted

技术标签:

【中文标题】每月最后一天加入第二张桌子【英文标题】:Last day of month joined to second table 【发布时间】:2017-10-09 08:35:46 【问题描述】:

我需要获取上个月的最后一天,然后将其加入另一个表以返回与日期相关的年/月列,但我正在努力实现我想要的。

我试过了:

SELECT b.yrmonth, LAST_DAY(ADD_MONTHS(SYSDATE,-1)) DT 
FROM dual a
INNER JOIN D_DAY b on DT = b.DT

年份月份只返回表中的所有内容,而不仅仅是一行,因此非常感谢任何帮助!

【问题讨论】:

Getting Last Day of Previous Month in Oracle Function的可能重复 @a_horse_with_no_name 不是重复的。 OP 知道如何获取上个月的最后一天;问题在于加入条件。 mcve 会很有帮助。 【参考方案1】:

您的查询是有效的:

SELECT b.yrmonth,
       'some constant masking b.DT' DT 
FROM   dual a
       INNER JOIN
       D_DAY b
       on ( b.DT = b.DT ) -- Always true

您不需要加入DUAL 表,需要在WHERE 子句中过滤您的表。

如果DT 日期列具有不同的时间分量:

SELECT yrmonth, dt
FROM   D_DAY
WHERE  DT >= TRUNC(LAST_DAY(ADD_MONTHS(SYSDATE,-1)))
AND    DT <  TRUNC(SYSDATE,'MM');

(这将允许数据库使用DT 列上的索引)

或者,如果您的 DT 列的日期始终包含在午夜的时间部分:

SELECT yrmonth, dt
FROM   D_DAY
WHERE  DT = TRUNC(LAST_DAY(ADD_MONTHS(SYSDATE,-1)));

【讨论】:

【参考方案2】:

您不需要加入dual 表。您可以简单地在where 子句中添加您的条件:

select *
from D_DAY b
where TRUNC(b.DT) = TRUNC(LAST_DAY(ADD_MONTHS(SYSDATE,-1)) 

并将date(带时间)转换为date,因为LAST_DAY函数返回date(带时间组件,如果要检查日期,则需要在之前转换。

【讨论】:

您不需要在 DATE 数据类型上使用 TO_DATELAST_DAY() 返回 DATE 数据类型,TO_DATE 接受字符串输入,因此 Oracle 必须执行隐式 TO_CHAR 并且实际上正在执行 TO_DATE( TO_CHAR( LAST_DAY( ... ), NLS_DATE_FORMAT ), 'DD-MON-YYYY' )。如果用户更改 NLS_DATE_FORMAT 会话参数以使其与显式格式模型不匹配(或者如果在默认 NLS_DATE_FORMAT 可能在国家之间更改时在国际上运行查询),这将失败。 我添加了演员表,因为 LAST_DAY() 返回的是 TIMESTAMP 数据类型;如果您尝试检查它,则返回 false:LAST_DAY(ADD_MONTHS(SYSDATE,-1)) = to_date('30/09/2017', 'dd/MM/YYYY') 它没有返回时间戳 - 它正在返回带有时间组件的日期(Oracle DATE 数据类型具有年/月/日/小时/分钟/秒组件)。如果不需要时间组件,则使用TRUNC 将其截断回午夜。使用TO_DATE 并依赖隐式TO_CHAR 是错误的解决方案。 好的,我同意 TRUNC 更好,但您仍然需要输入日期(带时间):) 不过谢谢您的解释。 'DD-MON-YYY' 不是trunc(datetime) 的有效格式模型。它必须是以下之一:docs.oracle.com/database/121/SQLRF/functions271.htm

以上是关于每月最后一天加入第二张桌子的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server学习记录之获取每月每季度每年第一天和最后一天

递归输入一个日期返回前12个月每月最后一天

每月最后一天返回

使用 Power Query 过滤每月第一天和最后一天的日期

每月最后一天

如何在mysql数据库中取得每月第一天和最后一天之间的数据?