SQL 服务器 : Where & Like Statements

标签 sql sql-server where

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

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

示例:instance001 产生 1 条记录。 instance002 产生 60。如果我使用 其中 inst_name 类似于“instance001”或 inst_name 类似于“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

最佳答案

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 ...

关于SQL 服务器 : Where & Like Statements,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38832348/

相关文章:

sql - 如何在 SQL 中写出/转换 YYYY-MM-DD 为 "Month, DD, YYYY"

sql - sql中如何根据多个条件删除记录

sql触发器消失

ruby-on-rails - 在 rails 中使用或子句搜索 [IN]

python - fast python numpy 哪里有功能?

linq-to-sql - Linq To SQL 'Where Or'运算符

c# - 我们在 MS-Access 中有交易吗?

php - 跨多个表的 MySQL 查询问题

sql - sql server 在插入时是否检查重复的 GUID?

sql-server - 是否有任何理由避免将 bigint 用作代理主键?