Oracle 中的 LAG 函数
Posted
技术标签:
【中文标题】Oracle 中的 LAG 函数【英文标题】:LAG Function in Oracle 【发布时间】:2017-05-24 09:18:25 【问题描述】:我有一个包含Create_date(DataType=Date)
列的表(事件)。
我想从以前的记录中获得天数或小时数的差异。就像下面的截图一样。
从第二个记录 Create_Date 我想减去第一个 Create_Date 和从第三个创建日期到第二个等等。我在 Oracle 中使用 LAG 函数,但不确定它是如何计算的。谁能帮我解决这个问题。
incident.create_date - lag(incident.create_date,1) OVER (ORDER BY incident.create_date) AS CREATEDATE_DIFF,
RN 1 我们有 Create_date (05/01/017 10:40:17 AM
【问题讨论】:
【参考方案1】:Oracle 中的日期差异以天数计算。如果差值小于一天,则返回的值将小于 1。
如果要将其转换为小时,则必须将结果乘以 24,分钟乘以 24*60,秒乘以 24*60*60。
例如:
select sysdate - trunc(sysdate) diff_in_days,
(sysdate - trunc(sysdate))*24 diff_in_hours,
(sysdate - trunc(sysdate))*24*60 diff_in_mins,
(sysdate - trunc(sysdate))*24*60*60 diff_in_secs
from dual;
DIFF_IN_DAYS DIFF_IN_HOURS DIFF_IN_MINS DIFF_IN_SECS
------------ ------------- ------------ ------------
0.4342245370 10.4213888888 625.28333333 37517
然后,您可能希望应用 ROUND(或者可能是 TRUNC/CEIL),具体取决于您希望输出的外观(例如,到 2 d.p.、到最近的分钟等)。
【讨论】:
感谢您的回复,但是如何在不使用任何 LAG 函数的情况下对 FirstDate 进行第二次创建减号。我附上了其计算差异但不确定其计算方式的屏幕截图。例如。第二条记录(05/01/017 10:49:37)- 05/01/017 上午 10:40:17(第一条记录)这意味着大约 0 小时 55 分 34 秒,但它显示了一些东西(0.001388888)。即使我将其 0.0 * 24 (IN Days) 舍入。 您将在完成所有计算后进行四舍五入(如果您提前四舍五入,您的计算会变得不那么准确!)。因此,round((<date2> - <date1>)*24*60, 2)
将获取您的两个日期,找出差异,将其乘以 24 和 60,然后将其四舍五入到小数点后两位。
如果你需要0天3小时29分10秒的答案,我建议你看看MT0的答案,顺便说一句。【参考方案2】:
如果您从另一个日期中减去一个日期,您将得到天数(或其分数)的差异。
您可以使用间隔获取此日期/小时/分钟/秒:
SELECT EXTRACT( DAY FROM createdate_diff ) AS days,
EXTRACT( HOUR FROM createdate_diff ) AS hours,
EXTRACT( MINUTE FROM createdate_diff ) AS minutes,
EXTRACT( SECOND FROM createdate_diff ) AS seconds,
createdate_diff
FROM (
SELECT NUMTODSINTERVAL(
create_date - lag(create_date) OVER (ORDER BY create_date),
'DAY'
) AS CREATEDATE_DIFF
FROM incident
);
或者您可以手动执行相同的计算:
SELECT TRUNC( createdate_diff ) AS days,
TRUNC( MOD( createdate_diff * 24, 24 ) ) AS hours,
TRUNC( MOD( createdate_diff * 24 * 60, 60 ) ) AS minutes,
MOD( createdate_diff * 24 * 60 * 60, 60 ) AS seconds,
createdate_diff
FROM (
SELECT create_date - lag(create_date) OVER (ORDER BY create_date)
AS CREATEDATE_DIFF
FROM incident
);
【讨论】:
澄清一下,此解决方案将产生按天、小时、分钟和秒划分的差异,而不是作为具有单个单位的数字(即 0 天、1 小时、53 分钟和 30 秒) , vs 6810 秒或 113.5 分钟)。我不确定这正是 OP 所追求的,但从他们提供的信息中不一定清楚! @Boneist 从OP's comment 看来,他们似乎想要(即使他们的示例中的输入值不正确)类似“0 小时 55 分 34 秒”的输出。 这与他们原始帖子中的days OR hours
不符!我并不是说这是一个错误的答案;我只是想为 OP 澄清一下,因为这可能正是他们想要的。
如果您愿意,也可以使用 CAST(create_date as TIMESTAMP) - LAG(create_date) OVER (ORDER BY create_date)
代替 NUMTODSINTERVAL
。【参考方案3】:
使用
......
(incident.create_date -
lag(incident.create_date,1) OVER (ORDER BY incident.create_date))
*24*60
AS CREATEDATE_DIFF_IN_MINS,.....
在minutes
中获取输出,该输出适合您的样本数据。或者进一步乘以60
得到seconds
的输出。
【讨论】:
谢谢,但我仍然没有得到,因为我正在使用您发布的内容。(incident.create_date - lag(incident.create_date,1) OVER (ORDER BY event.create_date))*24 *60 AS CREATEDATE_DIFF, Second Date(05/01/017 10:58:54 AM)-FirstDate(04/01/017 01:53:04 PM) 它得到 1.86666 差异大约是 21 小时 5 分钟,但结果我'使用上述代码 24*60 后,我得到 1.866。请帮助我 不确定你的意思。如果您想在几分钟内获得输出,我只是建议将您已经存在的结果乘以24*60
。您当前的输出是什么,您的期望是什么?以上是关于Oracle 中的 LAG 函数的主要内容,如果未能解决你的问题,请参考以下文章