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
我有上面看到的代码,当它显示关闭日期时显示小时,分钟和秒,但是当我按截止日期分组时,我需要这样才能按日期分组。任何想法我怎么能这样做?
答案 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 之前的那一天不到午夜,即覆盖整整一天