每当我重新排列where子句的条件时,我都会看到不同的查询结果;我想弄清楚为什么会这样。我被要求尝试弄清楚发生了什么,所以我可以使用一些帮助来确定可能导致问题的原因。要清楚,我们在运行select语句时没有收到错误,但是收到了意外的数据结果。这是一个Oracle数据库(我相信10克)。我们对同一领域有两个条件。第一个是确保结果大于30年前(这个数据库不是我自己设置的,但是拥有该应用程序的团队决定将created_date改为30,这是一个好主意)....第二个是更具体的日期范围是9月1日到10月1日。
SELECT created_date
FROM tableName
WHERE
created_date > sysdate - 11000 -- 30 years in the past
AND short_name like 'FOO%'
AND trunc(created_date) BETWEEN TO_DATE('09-01-2017', 'MM-DD-YYYY')
AND TO_DATE('10-01-2017', 'MM-DD-YYYY')
当运行上面的查询时,我们会在where子句末尾的条件之外接收带有created_date的结果。
但是,当我将created_date和sysdate之间的比较放在两个日期之间的比较后,我们会收到正确的结果。
SELECT created_date
FROM tableName
WHERE
short_name like 'FOO%'
AND trunc(created_date) BETWEEN TO_DATE('09-01-2017', 'MM-DD-YYYY')
AND TO_DATE('10-01-2017', 'MM-DD-YYYY')
AND created_date > sysdate - 11000 -- 30 years in the past
另外,我删除了“AND trunc(created_date)BETWEEN TO_DATE('09 -01-2017','MM-DD-YYYY')”的截断部分“到”AND created_date BETWEEN TO_DATE('09 -01-2017 ','MM-DD-YYYY')“并在之前或之后通过sysdate比较收到预期结果。
SELECT created_date
FROM tableName
WHERE
created_date > sysdate - 11000 -- 30 years in the past
AND short_name like 'FOO%'
AND created_date BETWEEN TO_DATE('09-01-2017', 'MM-DD-YYYY')
AND TO_DATE('10-01-2017', 'MM-DD-YYYY')
编辑:
数据库中有很多记录。创建日期为22-Sep-17只有1个结果。
SELECT created_date
FROM tableName
WHERE
created_date > sysdate - 11000 -- 30 years in the past
AND short_name like 'FOO%'
AND trunc(created_date) BETWEEN TO_DATE('09-01-2017', 'MM-DD-YYYY')
AND TO_DATE('10-01-2017', 'MM-DD-YYYY')
生成25个条目,created_date为17-Feb-04,1个为22-Sep-17。
这些将为两者之间的值提供两个微妙的不同结果 2017-10-01 00:00:01和2017-10-01 23:59:59查询使用TRUNC 将包括那个没有TRUNC范围的范围 排除。
预期的结果是在22-Sep-17的日期范围内返回记录;但是,我们收到了25条记录,所有记录都是日期为17-Feb-04 ....如果我删除created_date> sysdate - 11000我也收到了唯一一条记录。
答案 0 :(得分:1)
首先要确保结果大于30年前
你不减去30年,你减去11,000天大约(取决于闰年)30年零42天。
如果您想减去30年,请使用:
ADD_MONTHS( date_value, -30 * 12 )
第二个是更具体的日期范围是9月1日到10月1日。
这使得第一个条件无关紧要 - 如果它在2017-09-01
和2017-10-01
之间,则它将在过去30年内,并且您不需要第一个条件。
我删除了"
AND trunc(created_date) BETWEEN TO_DATE('09-01-2017', 'MM-DD-YYYY')
"的截断部分到"AND created_date BETWEEN TO_DATE('09-01-2017', 'MM-DD-YYYY')
"并在之前或之后通过sysdate比较收到预期结果。
这些将为2017-10-01 00:00:01
和2017-10-01 23:59:59
之间的值提供两个微妙不同的结果。使用TRUNC
的查询将包含不包含TRUNC
范围的范围。
此外,使用TRUNC
意味着Oracle不会在created_date
列上建立索引(并且需要TRUNC( created_date )
上基于函数的索引)。如果你想使用一个索引,那么只需使用该列并测试它是否大于或等于范围的开始并且小于范围的结束加上一天(包括最多23:59:59的那天)。
TRUNC
查询的简化等效项为:
SELECT created_date
FROM tableName
WHERE short_name like 'FOO%'
AND created_date >= DATE '2017-09-01' -- range start
AND created_date < DATE '2017-10-01' + INTERVAL '1' DAY -- range end + 1 day