摆脱约会的时间

时间:2015-05-01 08:31:08

标签: sql oracle datetime

SELECT close_date, close_UIN, count(*) as Amount_Closed_per_employee
FROM   t_return_master
where status = 'C' AND TO_DATE (close_date ,'DD-MON-YY') BETWEEN TO_DATE     
('~Date From~', 'DD/MM/YYYY') AND TO_DATE('~Date To~','DD/MM/YYYY') 
group by close_date, close_UIN
order by close_UIN

我有上面看到的代码,当它显示关闭日期时显示小时,分钟和秒,但是当我按截止日期分组时,我需要这样才能按日期分组。任何想法我怎么能这样做?

2 个答案:

答案 0 :(得分:2)

您可以在日期(在SELECT和GROUP BY子句中)使用TRUNC(),只使用默认参数,将小时/分钟/秒/毫秒设置为零。

SELECT TRUNC( close_date ) AS close_date_day,
       close_UIN,
       count(*) as Amount_Closed_per_employee
FROM   t_return_master
where  status = 'C'
AND    TO_DATE (close_date ,'DD-MON-YY')
         BETWEEN TO_DATE('~Date From~', 'DD/MM/YYYY')
         AND     TO_DATE('~Date To~','DD/MM/YYYY') 
group by TRUNC( close_date ), close_UIN
order by close_UIN

答案 1 :(得分:1)

最简单的方法是使用the trunc() function,默认情况下将日期值的时间部分设置为午夜:

SELECT trunc(close_date), close_UIN, ...
... 
group by trunc(close_date), close_UIN
order by close_UIN

请注意,您需要截断选择列表 group-by子句中的值。该函数也可以选择截断到不同的精度,例如删除秒,或者转到月的第一天等等:

select sysdate, trunc(sysdate), trunc(sysdate, 'SS') from dual;

SYSDATE             TRUNC(SYSDATE)      TRUNC(SYSDATE,'MI')
------------------- ------------------- -------------------
2015-05-01 09:37:48 2015-05-01 00:00:00 2015-05-01 09:37:00

有关详细信息,请参阅文档。

这是不正确的:

AND TO_DATE (close_date ,'DD-MON-YY') BETWEEN TO_DATE     
('~Date From~', 'DD/MM/YYYY') AND TO_DATE('~Date To~','DD/MM/YYYY')

由于close_date已经是一个日期列,您正在使用NLS_DATE_FORMAT隐式转换为字符串,然后使用'DD-MON-YY'显式转换回日期 - 正在使用两位数的年份,将导致自己的问题。对于具有不同设置的其他用户,行为可能会有所不同。

看起来你试图做trunc()相当于between覆盖整个最后一天,但你不会得到你期望的那一年(世纪) 。并且调用列上的任何函数将阻止使用它上的任何索引,除非您具有匹配的基于函数的索引(但仅在选择列表中使用trunc()并且分组依旧)。

如果您想要从'date from'开始到'date to'结尾的所有记录,您可以指定范围而不是'between' - 这是包容性的,但可能无法获得您期望的结果,具体取决于您的NLS设置,再次。类似的东西:

AND close_date >= TO_DATE('~Date From~', 'DD/MM/YYYY')
AND close_date < TO_DATE('~Date To~','DD/MM/YYYY') + 1

之后日期之后相当于在'日期'到23:59:59 之前的那一天不到午夜,即覆盖整整一天