百思不得其解的sql, 请大家帮忙看下

oldwolf1987 2013-05-21 10:37:15
本人最近在做开发的时候,写了如下一段SQL

SELECT A.SF_BILL_STATUS
FROM SYSADM.PS_SM_TAX_INV_REG1 A
WHERE A.INVOICE_DT BETWEEN TO_DATE('2013-01-10', 'YYYY-MM-DD') AND
TO_DATE('2013-01-12', 'YYYY-MM-DD')
AND ((A.SF_BILL_STATUS = 'C' AND
A.CANCEL_DT > TO_DATE('2013-01-26', 'YYYY-MM-DD')) OR
A.SF_BILL_STATUS = 'I')

很奇怪的是这个OR语句
OR A.SF_BILL_STATUS = 'I

如果删掉OR .. 执行就没问题. 但是加上就有问题
这是去掉OR
这是加上OR
但是如果在SQL后面多加一个条件比如说 AND 1=1或者别的, 就能出数据
多加条件后
实在不能理解,请帮忙解答下谢谢了, DB环境是Oracle 10g, tools: PLSQL

PS, 我在OR 条件上加上trim也能出结果.
OR TRIM(A.SF_BILL_STATUS) = 'I'
请问这是为什么呢?
(当然用Union也可以解决, 只是想找到为什么会这样. )
...全文
543 23 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
oldwolf1987 2013-06-18
  • 打赏
  • 举报
回复
算了,许久没得到答案,给分了.
扳手腕 2013-06-07
  • 打赏
  • 举报
回复
没看出sql有任何的问题,疼了。。。
yuyeyi 2013-06-03
  • 打赏
  • 举报
回复
直接用这个TRIM(A.SF_BILL_STATUS) = 'I'条件查询出SF_BILL_STATUS 的数据, 绝对是你的SF_BILL_STATUS的数据有问题。 仔细查找看看。
oldwolf1987 2013-06-03
  • 打赏
  • 举报
回复
引用 18 楼 yuyeyi 的回复:
直接用这个TRIM(A.SF_BILL_STATUS) = 'I'条件查询出SF_BILL_STATUS 的数据,
绝对是你的SF_BILL_STATUS的数据有问题。
仔细查找看看。

yuyeyi兄, 单独查过,这个条件的返回值是空.
另外我猜想数据库里可能有' ' 或者 ' I' 这种情况. 但是我查过他们的长度, 都是1.
oldwolf1987 2013-06-03
  • 打赏
  • 举报
回复
谢谢大家, 最终还是以trim的方式解决此问题. 具体原因还是不得而知. 如u010778803兄所说, 跟执行计划没任何关系.既然是 or 连接, 那么至少会将
(A.SF_BILL_STATUS = 'C' AND
       A.CANCEL_DT > TO_DATE('2013-01-26', 'YYYY-MM-DD'))
的结果显示出来才对. minitoy兄, 这段SQL的逻辑没问题, 需要先取 SF_BILL_STATUS = 'C' 并且有时间限制 CANCEL_DT > 2013-01-26. 然后再取 SF_BILL_STATUS = 'I' 的, 对与这个条件是没有时间限制的. 我查过相关的文档, 这两个条件的结果是不会受影响的. 但是这里确实取不出来, 我以为这应该是个BUG. 但是在Metalink上, 查不到相关的信息. 所以还需要数据库的高手来解决这个问题..
minitoy 2013-06-03
  • 打赏
  • 举报
回复
筛选条件的逻辑问题吧
T9Team 2013-05-31
  • 打赏
  • 举报
回复
SQL没发现问题,执行计划不可能改变sql的执行结果,不然这个bug提交给oracle估计也发财了 and或or的连接也没问题,还是请楼主把建表和数据的语句发出来,让大家仔细检查下
jhonjoe 2013-05-30
  • 打赏
  • 举报
回复
这个应该是or和and的问题,建议楼主提供下表结构及初始化数据,然后让大家写下sql实际了解下
善若止水 2013-05-24
  • 打赏
  • 举报
回复
楼主首先看看表中的数据,尤其是SF_BILL_STATUS为C和I时的INVOICE_DT,因为最终是要都有INVOICE_DT进行限制的。我估计是SF_BILL_STATUS为I时的INVOICE_DT不满足条件所致。 至于增加后又可以查到数据了,你得看看执行计划。我推测是改变了优先级,or的部分就没有执行。
onlykenny 2013-05-24
  • 打赏
  • 举报
回复
你把后面的条件放前面去执行一下,这个真的很诡异啊。
JackRio 2013-05-24
  • 打赏
  • 举报
回复
我始终认为和执行计划有关 执行顺序问题真心不见得 楼主 把两个的执行计划贴出来看看
oldwolf1987 2013-05-23
  • 打赏
  • 举报
回复
引用 11 楼 lzd_83 的回复:
了解sql的执行顺序这个问题就明白了。
请 lzd_83 明示下, 谢谢了.
Rotel-刘志东 2013-05-23
  • 打赏
  • 举报
回复
了解sql的执行顺序这个问题就明白了。
u010805381 2013-05-23
  • 打赏
  • 举报
回复
#5,同感,查询成功执行了,但没有查询结果。
oldwolf1987 2013-05-23
  • 打赏
  • 举报
回复
引用 9 楼 liaozw 的回复:
[quote=引用 6 楼 JAWKS_LONG 的回复:] 你同一个字段用AND,又OR,为什么不用直接用括号括起来OR呢? 你可以这样试试: SELECT A.SF_BILL_STATUS FROM SYSADM.PS_SM_TAX_INV_REG1 A WHERE A.INVOICE_DT BETWEEN TO_DATE('2013-01-10', 'YYYY-MM-DD') AND TO_DATE('2013-01-12', 'YYYY-MM-DD') AND ((A.SF_BILL_STATUS = 'C' OR A.SF_BILL_STATUS = 'I') AND A.CANCEL_DT > TO_DATE('2013-01-26', 'YYYY-MM-DD')) 不知道是不是符合您的需求,但是这种才是最直接明了的SQL.
楼主的SQL那个逻辑是SF_BILL_STATUS = 'C'的时候CANCEL_DT 要大于2013-01-26,而SF_BILL_STATUS = 'I'的时候,不管时间,你这一改,整个逻辑都不对了[/quote] 是的liaozw 兄说的对. 如果按照JAWKS_LONG兄的来改, 整个逻辑就变了. vanjayhsu兄, 照你所说, 那SF_BILL_STATUS='C'的结果应该出来才对啊.
JAWKS_LONG 2013-05-23
  • 打赏
  • 举报
回复
你同一个字段用AND,又OR,为什么不用直接用括号括起来OR呢? 你可以这样试试: SELECT A.SF_BILL_STATUS FROM SYSADM.PS_SM_TAX_INV_REG1 A WHERE A.INVOICE_DT BETWEEN TO_DATE('2013-01-10', 'YYYY-MM-DD') AND TO_DATE('2013-01-12', 'YYYY-MM-DD') AND ((A.SF_BILL_STATUS = 'C' OR A.SF_BILL_STATUS = 'I') AND A.CANCEL_DT > TO_DATE('2013-01-26', 'YYYY-MM-DD')) 不知道是不是符合您的需求,但是这种才是最直接明了的SQL.
vanjayhsu 2013-05-23
  • 打赏
  • 举报
回复
请楼主仔细看你的SQL结果,去掉OR的SF_BILL_STATUS='C',你加上OR之后
OR A.SF_BILL_STATUS = 'I
还是查SF_BILL_STATUS,但是这个字段的值是C,所以你查询不到结果。你加上其他的条件查询的又是另外一个字段了,所以能查询出结果。
JackRio 2013-05-23
  • 打赏
  • 举报
回复
引用 6 楼 JAWKS_LONG 的回复:
你同一个字段用AND,又OR,为什么不用直接用括号括起来OR呢? 你可以这样试试: SELECT A.SF_BILL_STATUS FROM SYSADM.PS_SM_TAX_INV_REG1 A WHERE A.INVOICE_DT BETWEEN TO_DATE('2013-01-10', 'YYYY-MM-DD') AND TO_DATE('2013-01-12', 'YYYY-MM-DD') AND ((A.SF_BILL_STATUS = 'C' OR A.SF_BILL_STATUS = 'I') AND A.CANCEL_DT > TO_DATE('2013-01-26', 'YYYY-MM-DD')) 不知道是不是符合您的需求,但是这种才是最直接明了的SQL.
楼主的SQL那个逻辑是SF_BILL_STATUS = 'C'的时候CANCEL_DT 要大于2013-01-26,而SF_BILL_STATUS = 'I'的时候,不管时间,你这一改,整个逻辑都不对了
JackRio 2013-05-23
  • 打赏
  • 举报
回复
把加上了OR A.SF_BILL_STATUS = 'I' 和没有加 OR A.SF_BILL_STATUS = 'I' 这两个sql的执行计划都拿出来先看看。我觉得应该从执行计划上面着手
oldwolf1987 2013-05-22
  • 打赏
  • 举报
回复
引用 3 楼 rabitsky 的回复:
楼主如果知道怎么回事,不妨通知大家一下,我们也想知道为什么。
我也没找到原因, 坐等高手回答..
加载更多回复(3)

17,382

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 基础和管理
社区管理员
  • 基础和管理社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧