簡體   English   中英

如何使用SQL計算列中的非連續值的數量?

[英]How to count number of non-consecutive values in a column using SQL?

這里跟進我的問題。 假設我在Oracle數據庫中有一個表,如下面的表(table_1),它跟蹤特定個人的服務參與:

name  day  srvc_ inv
bill  1  1
bill  2  1
bill  3  0
bill  4  0
bill  5  1
bill  6  0
susy  1  1
susy  2  0
susy  3  1
susy  4  0
susy  5  1

我的目標是獲得一個匯總表,列出所有獨特的個人,是否有服務參與和不同服務事件的數量(在這種情況下2為票據,3為susy),其中一個不同的服務事件由一個識別在幾天內打破活動。

為了獲得任何服務,我將使用以下查詢

SELECT table_1."Name", MAX(table_1."Name") AS "any_invl"
FROM table_1
GROUP BY table_1."Name"

但是,我不知道如何獲得服務涉及的數量(2)。 在R中使用靜態數據幀,您將使用運行長度編碼(請參閱我原來的問題),但我不知道如何在SQL中完成此操作。 此操作將在大量記錄上運行,因此將整個數據幀存儲為對象並在R中運行它是不切實際的。

編輯:我的期望輸出如下:

name  any_invl  n_srvc_inv
bill  1  2
susy  1  3

謝謝你的幫助!

像這樣的東西?

SQL> with test (name, day, srvc_inv) as
  2    (select 'bill', 1, 1 from dual union all
  3     select 'bill', 2, 1 from dual union all
  4     select 'bill', 3, 0 from dual union all
  5     select 'bill', 4, 0 from dual union all
  6     select 'bill', 5, 1 from dual union all
  7     select 'bill', 6, 0 from dual union all
  8     select 'susy', 1, 1 from dual union all
  9     select 'susy', 2, 0 from dual union all
 10     select 'susy', 3, 1 from dual union all
 11     select 'susy', 4, 0 from dual union all
 12     select 'susy', 5, 1 from dual
 13    ),
 14  inter as
 15    (select name, day, srvc_inv,
 16       nvl(lead(srvc_inv) over (partition by name order by day), 0) lsrvc
 17     from test
 18    )
 19  select name,
 20    sum(case when srvc_inv <> lsrvc and lsrvc = 0 then 1
 21             else 0
 22        end) grp
 23  from inter
 24  group by name;

NAME        GRP
---- ----------
bill          2
susy          3

SQL>

我建議使用lag() 這個想法是計算一個“1”,但只有當前面的值為零或為null

select name, count(*)
from (select t.*,
             lag(srvc_inv) over (partition by name order by day) as prev_srvc_inv
      from t
     ) t
where (prev_srvc_inv is null or prev_srvc_inv = 0) and
      srvc_inv = 1
group by name;

您可以使用lag()的默認值來簡化此操作:

select name, count(*)
from (select t.*,
             lag(srvc_inv, 1, 0) over (partition by name order by day) as prev_srvc_inv
      from t
     ) t
where prev_srvc_inv = 0 and srvc_inv = 1
group by name;

您可以嘗試以下查詢,具有LAG功能來處理srvc_invl中的更改

select name, 1 any_invl, count(case when diff = 1 then 1 end) n_srvc_inv
from (select name, day, srvc_inv - LAG(srvc_inv, 1, 0) OVER(ORDER BY name, day) diff
      from tab
      order by name, day) temp
group by name

是小提琴,供您參考。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM