SELECT DECODE((SELECT COUNT(*) FROM dual WHERE TO_CHAR(SYSDATE) BETWEEN TO_CHAR ('01/Jan/2013') AND TO_CHAR('01/Jan/2020')),1,'Yes','No') FROM dual;
Which returns - NO
SELECT DECODE((SELECT COUNT(*) FROM dual where to_date(SYSDATE) BETWEEN to_date ('01/Jan/2013') AND to_date('01/Jan/2020')),1,'Yes','No') FROM dual;
Which returns - YES
From (01/jan/2013) to (10/Jan/2013) - returns No
SELECT DECODE((SELECT COUNT(*) FROM dual WHERE TO_CHAR(SYSDATE) BETWEEN TO_CHAR ('01/Jan/2013') AND TO_CHAR('01/Jan/2020')),1,'Yes','No') FROM dual;
to
SELECT DECODE((SELECT COUNT(*) FROM dual WHERE TO_CHAR(SYSDATE) BETWEEN TO_CHAR ('01/Jan/2013') AND TO_CHAR('10/Jan/2020')),1,'Yes','No') FROM dual;
Returns - No,
But from 11/jan/2020 its returns Yes
SELECT DECODE((SELECT COUNT(*) FROM dual WHERE TO_CHAR(SYSDATE) BETWEEN TO_CHAR ('01/Jan/2013') AND TO_CHAR('11/Jan/2020')),1,'Yes','No') FROM dual;
Which returns - YES
我无法理解为什么oracle会这样返回,请告诉我这个问题。感谢。
答案 0 :(得分:1)
我不确定这是不是重复;虽然链接的问题涵盖了类似的基础,并且将字符串与字符串和日期与日期进行比较的建议当然是有效的,但您已经这样做了,我不确定它是否一定会帮助您理解您在此处看到的内容。 / p>
关键是查看字符串比较时实际字符串值是什么。我假设您的NLS_DATE_FORMAT为DD/Mon/YYYY
,因为这就是您编写固定日期的方式,但它也适用于默认的DD-MON-RR
。我也忽略了NLS_SORT和其他设置的潜在复杂情况。
select to_char(sysdate), to_char('01/Jan/2013'), to_char('01/Jan/2020') from dual;
TO_CHAR(SYSDATE) TO_CHAR('01/JAN/2013') TO_CHAR('01/JAN/2020')
-------------------- ---------------------- ----------------------
11/Dec/2013 01/Jan/2013 01/Jan/2020
首先,固定字符串的to_char()
没有做任何事情,你将字符串转换为字符串。但请考虑将这些值插入where
子句时会发生什么;
select decode(count(*), 1, 'Yes', 'No') from dual
where to_char(sysdate) between to_char('01/Jan/2013') and to_char('01/Jan/2020');
变为
select decode(count(*), 1, 'Yes', 'No') from dual
where '11/Dec/2013' between '01/Jan/2013' and '01/Jan/2020';
这纯粹是一个字符串比较;虽然它们仍然代表您的日期,但它们只是字符串。第一个字符的比较失败 - 1
中的第一个11/Dec/2013
与另外两个字符串中的0
进行比较,'1'
不在'0'
之间和'0'
。 (简化一点)。
当您与第10名进行比较时,
select decode(count(*), 1, 'Yes', 'No') from dual
where to_char(sysdate) between to_char('01/Jan/2013') and to_char('10/Jan/2020');
变为:
select decode(count(*), 1, 'Yes', 'No') from dual
where '11/Dec/2013' between '01/Jan/2013' and '10/Jan/2020';
失败,因为'11'
不在'01'
和'10'
之间。
在上一次查询中,
select decode(count(*), 1, 'Yes', 'No') from dual
where to_char(sysdate) between to_char('01/Jan/2013') and to_char('11/Jan/2020');
变为:
select decode(count(*), 1, 'Yes', 'No') from dual
where '11/Dec/2013' between '01/Jan/2013' and '11/Jan/2020';
和(稍微简化一点)比较成功,因为'11/D'
是'01/J'
和'11/J'
之间的字符串。
使用不同的格式掩码可以使其始终如一地工作,但唯一安全可靠的方法是将所有内容作为日期进行比较,并在to_date()
调用中明确说明日期格式模型固定值:
select decode(count(*), 1, 'Yes', 'No') from dual
where sysdate between to_date('01/Jan/2013', 'DD/Mon/YYYY')
and to_date('01/Jan/2020', 'DD/Mon/YYYY');
不要做to_date(sysdate)
;正如提到的链接问题那样,将字符串隐式转换为字符串,这在最好的情况下是没有意义的,但如果指定了格式模型,则会引入问题。如果您尝试删除当前日期的时间部分,则可以使用trunc(sysdate)
而不是转换为字符串并返回。