【发布时间】:2012-05-05 15:31:48
【问题描述】:
有没有办法在 oracle 中平均多个日期? avg 没有任何好处。
谢谢。
【问题讨论】:
-
什么是“平均”日期?我认为你需要更具体地说明你想要做什么。
有没有办法在 oracle 中平均多个日期? avg 没有任何好处。
谢谢。
【问题讨论】:
“平均日期”的定义是主观的,但您可以将日期转换为儒略数,然后将它们平均,四舍五入,然后再转换回日期。
create table dates (dt DATE);
insert into dates
values ('24-APR-2012');
insert into dates
values ('01-JAN-2012');
insert into dates
values ('01-JAN-2013');
insert into dates
values ('25-DEC-1900');
select to_date(round(avg(to_number(to_char(dt, 'J')))),'J')
from dates;
这是 SQL Fiddle:http://sqlfiddle.com/#!4/98ce9/1
【讨论】:
oracle 中的“中位数”函数以一种简洁的方式完成了其他答案的作用。
这里是 Oracle 文档的链接 - https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions086.htm
它可以将数值数据类型或可隐式转换为数字的非数值数据类型作为 arg。
SQL> desc x1
Name Null? Type
----------------------------------------- -------- ----------------------------
A NOT NULL NUMBER
D DATE
SQL> select * from x1;
A D
---------- ---------
1 11-DEC-14
2 13-DEC-14
3 22-DEC-14
4 02-DEC-14
SQL> select median(d) from x1;
MEDIAN(D)
---------
12-DEC-14
【讨论】:
Oracle 自然地处理一些日期算术 - 例如 TRUNC(SYSDATE) + 1 将返回明天的日期。
所以另一种方法是将您的日期与常数进行比较:
1) 将距离以天为单位与一个常数(例如 SYSDATE)进行比较
2) 对该计算进行平均,然后四舍五入
3) 将平均值与 SYSDATE 进行比较并转换回日期。
这是一些执行此操作的代码(将 dt 替换为包含您的数据的任何字段)
TO_DATE(
TRUNC(SYSDATE) - ROUND(AVG(TRUNC(SYSDATE) - TRUNC(dt)))
)
在一些样本数据上,运行时间不到 Dan A. 上述方法的一半,并且产生了相同的输出。仅针对具有过去日期的数据对其进行了测试,但我看不出有任何明显的原因表明它不会泛化(我意识到处理 DATETIME 数据时的著名遗言......)
【讨论】:
SYSDATE + AVG( dt - SYSDATE )
无需将日期转换为日期。如果您不希望结果中包含时间,请截断整个表达式。如果您不想在计算平均值时使用时间,请截断日期列 (dt)。 MEDIAN 与 AVG 不同。
【讨论】: