SQL:获取正在运行的记录行增量
假设我们有一个列为RowID和Call的表: 我想用SQL查询所需的最后一列,如下所示: 每次调用都是“A”,请返回,直到再次找到“A”,并计算两个“A”条目之间的记录数 示例:rowid4有“A”,最近的前置项在rowid2中。在rowid2和rowid4之间,我们有一个调用“B”,所以我们计算1SQL:获取正在运行的记录行增量,sql,Sql,假设我们有一个列为RowID和Call的表: 我想用SQL查询所需的最后一列,如下所示: 每次调用都是“A”,请返回,直到再次找到“A”,并计算两个“A”条目之间的记录数 示例:rowid4有“A”,最近的前置项在rowid2中。在rowid2和rowid4之间,我们有一个调用“B”,所以我们计算1 使用ANSI SQL是否有一种优雅而高效的方法可以做到这一点?您可以这样做: SELECT a.rowid - b.rowid FROM table as a, (SELECT row
使用ANSI SQL是否有一种优雅而高效的方法可以做到这一点?您可以这样做:
SELECT a.rowid - b.rowid
FROM table as a,
(SELECT rowid FROM table where rowid < a.rowid order by rowid) as b
WHERE <something>
ORDER BY a.rowid
因为我不能说您使用的是哪种DBMS,所以这是一种伪代码,可以基于您的系统工作 您可以使用查询来查找前一个调用=一行。然后,您可以计算该行和当前行之间的行数:
select RowID
, `Call`
, (
select count(*)
from YourTable t2
where RowID < t1.RowID
and RowID > coalesce(
(
select RowID
from YourTable t3
where `Call` = 'A'
and RowID < t1.RowID
order by
RowID DESC
limit 1
),0)
)
from YourTable t1
我将通过首先查找前一个值的rowid来实现这一点。然后计算两者之间的数值 以下查询使用相关子查询实现此逻辑:
select t.*,
(case when t.call = 'A'
then (select count(*)
from table t3
where t3.id < t.id and t3.id > prevA
)
end) as InBetweenCount
from (select t.*,
(select max(rowid)
from table t2
where t2.call = 'A' and t2.rowid < t.rowid
) as prevA
from table t
) t;
如果您知道rowid是连续的,没有间隔,您可以在外部查询中使用减法而不是子查询进行计算。下面是使用窗口函数的另一种解决方案:
with flagged as (
select *,
case
when call = 'A' and lead(call) over (order by rowid) <> 'A' then 'end'
when call = 'A' and lag(call) over (order by rowid) <> 'A' then 'start'
end as change_flag
from calls
)
select t1.rowid,
t1.call,
case
when change_flag = 'start' then rowid - (select max(t2.rowid) from flagged t2 where t2.change_flag = 'end' and t2.rowid < t1.rowid) - 1
when call = 'A' then 0
end as desiredout
from flagged t1
order by rowid;
CTE首先标记每个A块的开始和结束,然后最终选择使用这些标记获取一个块的开始和上一个块的结束之间的差异
如果rowid不是无间隙,则可以在CTE内轻松添加无间隙rownumber以计算差值
不过,我对表演不太确定。如果戈登的回答更快,我也不会感到惊讶
SQLFiddle示例:信不信由你,如果这两列都被索引了,这将非常快
select r1.RowID, r1.CallID, isnull( R1.RowID - R2.RowID - 1, 0 ) as DesiredOut
from RollCall R1
left join RollCall R2
on R2.RowID =(
select max( RowID )
from RollCall
where RowID < R1.RowID
and CallID = 'A')
and R1.CallID = 'A';
以下是。rowid是否自动生成并存储在数据库中?您使用的是什么数据库?rowid没有间隙。我将尝试所有答案并比较运行时,因为所讨论的表是巨大的。@Juergen:严格地说,这个答案不是ANSI SQL btw。
select r1.RowID, r1.CallID, isnull( R1.RowID - R2.RowID - 1, 0 ) as DesiredOut
from RollCall R1
left join RollCall R2
on R2.RowID =(
select max( RowID )
from RollCall
where RowID < R1.RowID
and CallID = 'A')
and R1.CallID = 'A';