SQL Server:Where&与语句一样

时间:2016-08-08 14:50:50

标签: sql sql-server where

我的SQL游戏相当生疏。我有一些代码(见下文)检查数据库实例(instance001,instance002等),然后查找LAST_READ和LAST_WRITE字段为空时,以及上次重置时。顶部没什么。

我遇到的问题是如何在多个实例中执行此操作。你会看到我评论了一个部分。如果我添加适当的OR语句(or inst_name like 'instance002'),它就不会得到我正在寻找的结果。

示例:instance001产生1条记录。 instance002产生60.如果我使用 where inst_name like 'instance001' or inst_name like 'instance002' 我得到210条记录。我如何操纵SQL来提供61?

declare @timeString nvarchar(50) = CONVERT(varchar(24), GETDATE(), 120)
select DB_NAME, INST_NAME, MIN([LAST_SRVR_RST]) AS MIN_SRVR_RST, LAST_READ, LAST_WRITE, LOG_DATE=@timeString
from CMS_DB_LAST_READ_WRITE     -- Targeted DB with data.
where inst_name                 -- Targeted instance(s)
    like 'instance001'
    /*
    like 'instance002'
    like 'instance003'  
    like 'instance004'
    */
    and LAST_READ is null       -- Both read and write must be null
    and LAST_WRITE is null      -- to show no activity.
    --and [LAST_SRVR_RST] = MIN([LAST_SRVR_RST])
group by DB_NAME, INST_NAME, LAST_SRVR_RST, LAST_READ, LAST_WRITE

1 个答案:

答案 0 :(得分:4)

AND takes precedence over OR,您需要使用括号对这两个条件进行分组:

...
WHERE (inst_name = 'instance001' OR inst_name = 'instance002')
AND   LAST_READ  IS NULL 
AND   LAST_WRITE IS NULL
GROUP BY ... 

注意:我将使用率从LIKE更改为=,因为您正在寻找完全匹配,并且使用LIKE没有多大意义那种情况。

分组的原因是由于上面提到的优先顺序。这个顺序是:

Level   Operators
1       ~ (Bitwise NOT)
2       * (Multiply), / (Division), % (Modulo)
3       + (Positive), - (Negative), + (Add), (+ Concatenate), - (Subtract), & (Bitwise AND), ^ (Bitwise Exclusive OR), | (Bitwise OR)
4       =, >, <, >=, <=, <>, !=, !>, !< (Comparison operators)
5       NOT
6       AND
7       ALL, ANY, BETWEEN, IN, LIKE, OR, SOME
8       = (Assignment)

这意味着,您的所有AND语句都将首先进行评估。完成所有评估后,将评估您的OR语句。

这使您的查询看起来更像编译器:

WHERE   
(
        inst_name = 'instance001'
AND     LAST_READ  IS NULL
AND     LAST_WRITE IS NULL
)
OR      inst_name = 'instance002'

这就是为什么你得到210个结果,而不是预期的61,因为它在instance002中提取了所有记录,忽略了你的其他WHERE过滤器。

重写查询,将上述两个条件分组,对编译器来说就是这样:

WHERE   
(
        LAST_READ  IS NULL
AND     LAST_WRITE IS NULL
)
AND      
(       
        inst_name = 'instance002'
OR      inst_name = 'instance001'
)

这应该是您期望的逻辑条件。

另一种可以在没有AND / OR分组的情况下编写此查询的替代方法是使用IN子句:

...
WHERE inst_name IN ('instance001', 'instance002')
AND   LAST_READ IS NULL
AND   LAST_WRITE IS NULL
GROUP BY ...