[英]SQL: Get running row delta for records
假設我們有一個帶有RowID
和Call
列的表:
RowID Call DesiredOut
1 A 0
2 A 0
3 B
4 A 1
5 A 0
6 A 0
7 B
8 B
9 A 2
10 A 0
我想對SQL的最后一列DesiredOut
進行查詢,如下所示:每次Call
為'A'時,請返回直到再次找到'A'並計算兩個'A'條目之間的記錄數。
示例: RowID
4具有“ A”,而最接近的前任在RowID
2中。在RowID
2和RowID
4之間,我們有一個Call
“ B”,因此我們計為1。
使用ANSI SQL是否有一種優雅而高效的方法?
我將首先找到上一個“ A”值的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
是連續的且沒有間隙,則可以在外部查詢中僅使用減法而不是子查詢來進行計算。
您可以使用查詢來查找先前的Call = A
行。 然后,您可以計算該行與當前行之間的行數:
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
這是使用窗口函數的另一種解決方案:
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中添加無間隙的行號以計算差異。
我不確定性能。 如果戈登的答案更快,我不會感到驚訝。
SQLFiddle示例: http ://sqlfiddle.com/#!15/e1840/1
信不信由你,如果為兩列建立索引,這將非常快。
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';
這是小提琴 。
您可以這樣做:
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,這是一種更多的偽代碼,可以根據您的系統工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.