2016-09-19 92 views
0

我在查询中的Where子句有问题。为什么第一个查询给出与第二个查询不同的结果?SQL Where子句更改导致意外的结果

第一个查询是:

select distinct 
    [Event Code] = evt_code, 
    [Event Category] = etc_code, 
    [Acronym] = evt_acronym_ext, 
    [Remit To Sort Name] = cst_sort_name_dn, 
    [ReC#] = cst_recno, 
    [Honorarium Amount] = case when fac_honorarium_amount_ext is null then 0.00 else fac_honorarium_amount_ext end, 
    [Speaker type] = spt_code 
from 
    ev_event (nolock) 
inner join 
    ev_event_ext (nolock) on evt_key_ext = evt_key 
inner join 
    ev_event_category (nolock) on etc_key = evt_etc_key and etc_delete_flag = 0 
inner join 
    ev_event_faculty (nolock) on fac_evt_key = evt_key and fac_delete_flag = 0 
inner join 
    ev_event_faculty_ext (nolock) on fac_key_ext = fac_key --and fac_honorarium_amount_ext is not null and fac_honorarium_amount_ext > 0.0 
inner join 
    co_customer (nolock) on cst_key = fac_cst_key and cst_delete_flag = 0 
inner join 
    ev_event_speaker (nolock) on spk_fac_key = fac_key and spk_delete_flag = 0 
inner join 
    ev_event_speaker_type (nolock) on spt_key = spk_spt_key and spt_delete_flag = 0 
where 
    evt_code like '416%A' or evt_code like '516%A' 
    and spt_code in ('Ed Fdn Speaker', 'Ed Fdn Author', 'Ed Fdn Conf Chair') 
order by 
    evt_code 

第二个查询是:

select distinct 
    [Event Code] = evt_code, 
    [Event Category] = etc_code, 
    [Acronym] = evt_acronym_ext, 
    [Remit To Sort Name] = cst_sort_name_dn, 
    [ReC#] = cst_recno, 
    [Honorarium Amount] = case when fac_honorarium_amount_ext is null then 0.00 else fac_honorarium_amount_ext end, 
    [Speaker type] = spt_code 
from 
    ev_event (nolock) 
inner join 
    ev_event_ext (nolock) on evt_key_ext = evt_key 
inner join 
    ev_event_category (nolock) on etc_key = evt_etc_key and etc_delete_flag = 0 
inner join 
    ev_event_faculty (nolock) on fac_evt_key = evt_key and fac_delete_flag = 0 
inner join 
    ev_event_faculty_ext (nolock) on fac_key_ext = fac_key --and fac_honorarium_amount_ext is not null and fac_honorarium_amount_ext > 0.0 
inner join 
    co_customer (nolock) on cst_key = fac_cst_key and cst_delete_flag = 0 
inner join 
    ev_event_speaker (nolock) on spk_fac_key = fac_key and spk_delete_flag = 0 
inner join 
    ev_event_speaker_type (nolock) on spt_key = spk_spt_key and spt_delete_flag = 0 
where 
    (evt_code like '416%A' 
    and spt_code in ('Ed Fdn Speaker', 'Ed Fdn Author', 'Ed Fdn Conf Chair')) 
    or 
    (evt_code like '516%A' 
    and spt_code in ('Ed Fdn Speaker', 'Ed Fdn Author', 'Ed Fdn Conf Chair')) 
order by 
    evt_code 
+0

第一个查询将返回带有evt_code LIKE'416%A'的所有行,而不管spt_code。第二个使用AND运算符,所以这些行也必须有一个指定的spt_code值。 –

+0

这与您的WHERE条款的评估顺序有关,特别是当第二个查询使用影响评估顺序的括号时。因此,在您的第一个查询中,您发现结果集的事件代码为“416%A”,但未通过扬声器类型进行过滤? –

+2

设置[坏习惯踢 - 把NOLOCK无处不在](http://blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere/) - 它是*不推荐*到处使用 - 完全相反! –

回答

1

你的第一个查询您正在评估 '416%A' 由它的自我。你可以用只有在括号来避免这个...

where (evt_code like '416%A' or evt_code like '516%A') AND 
spt_code in ('Ed Fdn Speaker', 'Ed Fdn Author', 'Ed Fdn Conf Chair') 
0

数据库被解释第一where子句如下:

evt_code like '416%A' 
and (spt_code in ('Ed Fdn Speaker', 'Ed Fdn Author', 'Ed Fdn Conf Chair') 
    or evt_code like '516%A') 
    ) 

纯英文:如果evt_code就像'416%A',那么如果spt_code是3项中的任何一项,或者evt_code是516%A,或者两者都满足,则满足where子句。

从技术上讲,数据库添加自己的括号并不准确,但这是一个很好的方式来描绘它。