我可以在没有 CURSOR 的情况下编写此查询吗?
Posted
技术标签:
【中文标题】我可以在没有 CURSOR 的情况下编写此查询吗?【英文标题】:Can I write this query without CURSORs? 【发布时间】:2013-01-23 19:04:04 【问题描述】:我试图找出在同一类别的另一个表中找到的时间戳的阈值时间内发生的事件数。改变 delta 的最快方法是什么(在下面给出的情况下,delta 是 5 分钟)?我刚刚使用游标测试了一种方法(将变量设置为 5,然后继续递增并执行相同的查询),但每次迭代需要 10 秒。在我的实际数据中,#EVENTS 中的行数大约等于 100K,而#CHANGES 大约是 500K。
我的表格如下:
CREATE TABLE #EVENTS(Category varchar(20), Timestamp datetime)
GO
INSERT INTO #EVENTS VALUES('A', '2013-01-23 05:02:00.000')
INSERT INTO #EVENTS VALUES('A', '2013-01-23 05:04:00.000')
INSERT INTO #EVENTS VALUES('B', '2013-01-23 05:03:00.000')
INSERT INTO #EVENTS VALUES('B', '2013-01-21 05:02:00.000')
GO
CREATE TABLE #CHANGES(Category varchar(10), Timestamp datetime)
GO
INSERT INTO #CHANGES VALUES('A', '2013-01-23 05:00:00.000')
INSERT INTO #CHANGES VALUES('B', '2013-01-21 05:05:00.000')
SELECT *
FROM
(
SELECT X.Category, X.Timestamp, Y.Timestamp BeforeT, DATEADD(MINUTE, 5, Y.Timestamp) AfterT
FROM #EVENTS X, #CHANGES Y
WHERE X.Category = Y.Category
) X
WHERE X.Timestamp BETWEEN BeforeT AND AfterT
DROP TABLE #CHANGES
DROP TABLE #EVENTS
GO
【问题讨论】:
你明白隐式连接是一种非常糟糕的编程习惯和 SQL 反模式吗?它们在 SQL Server 中尤其糟糕,因为当前版本不支持左连接隐式语法,并且在更高级的版本中不正确,并且混合隐式和显式连接通常会导致不正确的结果。您还可以得到意外的交叉连接。这种语法几年前就被取代了,本世纪没有理由使用它。 @HLGEM:感谢您纠正我。你对这个被弃用是正确的。我已经更改了我的代码,为了我自己的未来参考,一个相关的线程在这里:***.com/questions/44917/… 【参考方案1】:这就是你要找的吗?它对定义增量的 CTE 进行交叉连接:
with deltas as (
select 5 as delta union all
select 10 union all
select 20
)
SELECT *
FROM (SELECT e.Category, e.Timestamp, c.Timestamp BeforeT,
DATEADD(MINUTE, deltas.delta, c.Timestamp) AfterT,
deltas.delta
FROM #EVENTS e join
#CHANGES c
on e.Category = c.Category cross join
deltas
) X
WHERE X.Timestamp BETWEEN BeforeT AND AfterT
我还修正了你的别名。当别名与基础表名相关时,查询的读取效果会更好。
【讨论】:
+1 是的!这太棒了~您对我如何通过这种方式自动创建更长范围的增量表有什么建议吗? 将此作为另一个问题提出,人们往往不会看已回答的问题 @Legend 。 . .最简单的方法是将值放在 Excel 中的一列中,然后在另一列中创建一个类似=" select "&A1&" as delta union all "
的公式,复制公式,并编辑第一行和最后一行以使其语法准确。以上是关于我可以在没有 CURSOR 的情况下编写此查询吗?的主要内容,如果未能解决你的问题,请参考以下文章
我可以在不编写扩展的情况下编写 FlexBuilder 脚本吗?