Raf*_*off 0 performance t-sql sql-server-2008-r2 query-performance
SELECT *
FROM SameLogTable
WHERE ID_Table IN (SELECT ID_Table-1
FROM SameLogTable
WHERE <SameCondition>) OR
ID_Table IN (SELECT ID_Table
FROM SameLogTable
WHERE <SameCondition>) OR
ID_Table IN (SELECT ID_Table+1
FROM SameLogTable
WHERE <SameCondition>)
Run Code Online (Sandbox Code Playgroud)
此查询在日志记录表上运行,我想选择特定事件,以及这些事件之前和之后的事件。这个解决方案感觉丑陋且效率低下,为此编写更好的方法是什么?
示例:如果我对 LogTable 的 ID 为 4 和 23 的行感兴趣,我想得到以下结果:
ID Column1 Column2 ...
3 ... ...
4 ... ...
5 ... ...
22 ... ...
23 ... ...
24 ... ...
Run Code Online (Sandbox Code Playgroud)
这些都是来自同一 LogTable 的所有行,除了我使用 WHERE 指定第 4 行和第 23 行,并且我希望 Select 自动返回第 3,5 行(第 4 行)和第 22、24 行(第 23 行)。
总结结果:
MyQuery: 16s
UNION ALL: 4s
Join: ~0s
Run Code Online (Sandbox Code Playgroud)
感谢您的回复!
假设它ID是表的主键(或具有唯一约束),您可以使用此变体:
SELECT t.*
FROM SameLogTable AS t
JOIN ( SELECT id
FROM SameLogTable
WHERE <SameCondition>
) AS c
ON t.id = c.id -1
OR t.id = c.id
OR t.id = c.id +1 ;
Run Code Online (Sandbox Code Playgroud)
注意:如果id有差距,这很有可能,上面的方法不会按预期工作,您的原始查询也不会。ROW_NUMBER()可以帮助您:
; WITH cte AS
( SELECT t.*,
rn = ROW_NUMBER() OVER (ORDER BY t.id)
FROM SameLogTable AS t
)
SELECT t.*
FROM cte AS t
JOIN ( SELECT rn
FROM cte
WHERE <SameCondition>
) AS c
ON t.rn = c.rn - 1
OR t.rn = c.rn
OR t.rn = c.rn + 1 ;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
103 次 |
| 最近记录: |