每月最后一天加入第二张桌子
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_DATE
。 LAST_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学习记录之获取每月每季度每年第一天和最后一天