Eri*_*rik 3 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
Run Code Online (Sandbox Code Playgroud)
AND优先于OR,您需要使用括号将两个条件分组:
...
WHERE (inst_name = 'instance001' OR inst_name = 'instance002')
AND LAST_READ IS NULL
AND LAST_WRITE IS NULL
GROUP BY ...
Run Code Online (Sandbox Code Playgroud)
注意:我将用法从 更改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)
Run Code Online (Sandbox Code Playgroud)
这意味着,AND将首先评估您的所有语句。在它们都被评估后,然后你的OR陈述被评估。
这使您的查询在编译器看来更像这样:
WHERE
(
inst_name = 'instance001'
AND LAST_READ IS NULL
AND LAST_WRITE IS NULL
)
OR inst_name = 'instance002'
Run Code Online (Sandbox Code Playgroud)
这就是为什么你得到 210 个结果,而不是预期的 61 个,因为它把所有记录拉入instance002,不考虑你的其他WHERE过滤器。
重写对上述两个条件进行分组的查询,对于编译器来说应该是这样的:
WHERE
(
LAST_READ IS NULL
AND LAST_WRITE IS NULL
)
AND
(
inst_name = 'instance002'
OR inst_name = 'instance001'
)
Run Code Online (Sandbox Code Playgroud)
这应该是您期望的逻辑条件。
无需AND/OR分组即可编写此查询的另一种替代方法是使用IN子句:
...
WHERE inst_name IN ('instance001', 'instance002')
AND LAST_READ IS NULL
AND LAST_WRITE IS NULL
GROUP BY ...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
65 次 |
| 最近记录: |