如何使用保留订单的运行计数形成查询

Posted

技术标签:

【中文标题】如何使用保留订单的运行计数形成查询【英文标题】:How do I form a query with a running count retaining the order 【发布时间】:2012-08-07 08:24:45 【问题描述】:

我有一个如下所示的跟踪表

我想得到一个运行总计,它看起来像以下输出 - 保留订单非常重要 - 因为这是存储的 porcedures 的执行顺序 - 这将帮助我分析系统中的瓶颈

我试过了

select max(RowNumber),objectname, count(1) from rob
where eventclass = 42
group by objectname

但这会破坏订单

这在 SQL 中是否可行?

更新: 我试过这个

select RowNumber,objectname, count(1) from rob
where eventclass = 42
group by objectname,RowNumber
order by RowNumber

但是这个(因为查询非常正确地说按行号分组(必须有它才能按顺序排列))

【问题讨论】:

除非明确指定,否则没有顺序。是maya。 顺序是原始表中的行号 - 我已经用按部分排序的查询更新了问题 您想通过计算具有相同对象名的相邻(按行号)记录来压缩跟踪表吗?如果是这样,您使用的是哪个版本的 Sql Server? +1 是的,这就是我在下面的答案完美之后的那种 - 我有 SQL 2005 分析器,但数据库的 2008 快速版本:( 【参考方案1】:
select objectname, 
       count(*)
from (
     select RowNumber,
            objectname,
            row_number() over(order by RowNumber) - row_number() over(order by objectname, RowNumber) as grp
     from rob
     where eventclass = 42
     ) as T
group by grp, objectname
order by min(RowNumber)

使用表变量的工作示例。

declare @T table
(
  RowNumber int,
  objectname varchar(50)
)

insert into @T values
(8, 'f_system_log_init'),
(10, 'f_purge_system_log'),
(25, 'f_system_log_msg'),
(65, 'f_system_log_msg'),
(104, 'f_system_log_msg'),
(143, 'f_system_log_msg'),
(182, 'f_system_log_msg'),
(221, 'f_system_log_msg'),
(5015, 'f_get_system_logs_parent_log_id_for_dataloader'),
(5055, 'f_system_log_msg'),
(5096, 'f_system_log_msg')

select objectname, 
       count(*)
from (
     select RowNumber,
            objectname,
            row_number() over(order by RowNumber) - row_number() over(order by objectname, RowNumber) as grp
     from @T
     ) as T
group by grp, objectname
order by min(RowNumber)

结果:

objectname                                         
-------------------------------------------------- -----------
f_system_log_init                                  1
f_purge_system_log                                 1
f_system_log_msg                                   6
f_get_system_logs_parent_log_id_for_dataloader     1
f_system_log_msg                                   2

【讨论】:

另一个 +1 是我的 - 并且认为我正在考虑自我加入 :-( 谢谢你的这个绝妙主意。差距和岛屿将永远不会再一样了 ;-) @NikolaMarkovinović 我不能相信这种技术。 Itzik Ben-Gan 在SQL Server MVP Deep Dives- Chapter 5 Gaps and Islands 的第 68 页上对此进行了描述。【参考方案2】:

试试这个:

;WITH CTE as (select *,ROW_NUMBER() over(order by rownumber,objectname) rn from test101)

,CTE1 as(
select *,1 as incr from CTE where rn=1 
union all
select t.*,
CASE WHEN t.objectname=c.objectname then incr else incr+1 end  as incr
from CTE t inner join CTE1 c
on t.rn=c.rn+1
)

select max(objectname),count(incr) from CTE1
group by incr

【讨论】:

以上是关于如何使用保留订单的运行计数形成查询的主要内容,如果未能解决你的问题,请参考以下文章

运行查询以从大查询中获取事件计数

如何保留 $in 查询的游标顺序? [复制]

如何保留 $in 查询的游标顺序? [复制]

MDX 计算的测量计数

如何使用计数查询来(自动)更新表中的列

在 laravel 中,我如何生成一个计数数组?