为什么我在两种方式比较日期时会得到不同的结果?

时间:2016-04-12 10:50:58

标签: sql oracle

此查询:

select count(*), trim(data_date) 
from man
where data_status = 'received' and data_date > sysdate-7
group by trim(data_date);

给出的结果如下:

199 05-APR-16

但是这个查询:

select count(*), trim(data_date)
from man 
where data_status = 'received' and trunc(data_date) = date '2016-04-05'
group by trim(data_date);

给出的结果如下:

347 05-APR-16

为什么查询会在同一天给出不同的结果?

1 个答案:

答案 0 :(得分:3)

因为您的man_date_sub值不是全部在午夜。如果继续运行第一个查询,则返回的记录数将(可能)逐渐减少。这只发生在一周前的第五次计数中。你的sysdate - 7是一个移动的目标,不仅仅是你每天都在移动,而是在白天时间过去。

您可以使用以下方式查看时间:

select to_char(man_date_sub, 'YYYY-MM-DD HH24:MI:SS'),
  to_char(sysdate - 7, 'YYYY-MM-DD HH24:MI:SS'),
  man_date_sub - (sysdate - 7)
from man
where trunc(man_date_sub) = date '2016-04-05';

您会看到有些时间在当前sysdate时间之前,而其他时间有时间。第三个生成的列将显示一些正值和一些负值。

在第二个查询中,您将trunc(man_date_sub)date '2016-04-05'进行比较,sysdate将时间部分设置为午夜,而select count(*), trim(man_date_sub) from man where man_status = 'SUBMITTED' and man_date_sub > trunc(sysdate)-7 group by trim(man_date_sub); 也是在午夜;所以那天所有记录现在都匹配。

你可以在7天的范围内回到午夜,并通过截断'05-APR-16'获得相同的结果:

select count(*), to_char(man_date_sub, 'YYYY-MM-DD')
from man
where man_status = 'SUBMITTED' and man_date_sub > trunc(sysdate)-7
group by to_char(man_date_sub, 'YYYY-MM-DD');

你使用the trim() function有点奇怪;你所做的就是从字符串if (key == 's'){ if (isAmbientOn){ //if it is true turn the ambient off by setting the R,G,B values to 0 global_ambient[0] = 0; global_ambient[1] = 0; global_ambient[2] = 0; isAmbientOn = false; } else{ //if it is false tuen the ambient on by setting it to a value - 0.4 global_ambient[0] = 0.4; global_ambient[1] = 0.4; global_ambient[2] = 0.4; isAmbientOn = true; } } 中删除前导空格和尾随空格,这实际上并没有做任何事情。您还依赖于使用会话NLS_DATE_FORMAT将日期的implcit转换为字符串。最好指定格式:

void CDrawModel::myDrawGLScene(GLvoid)      // Here's Where We Do All The Drawing{
//set up the ambient light in myDrawGLScene so we can switch it on and off on 's' key press...
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);

{

如果您在具有包含时间元素的NLS_DATE_FORMAT的会话中运行原始查询,那么您将无法获得预期的结果。

我不确定您是否会将其与trunc()混淆,但显然您已在其他地方使用它。截断日期会将时间部分设置为午夜(默认情况下;它可以执行其他操作),但将其保留为日期,这可能适合分组,但仍应明确格式化以供显示。