簡體   English   中英

SQL 查詢求和列,直到滿足行條件並繼續求和列

[英]SQL query sum column till a row condition met and continue sum column

數據:

在此處輸入圖像描述

SQL Server 2012 - 我需要“掃描”如上所示的表格並總結持續時間列,直到在 Paycode 列中有“BREAK”的行。

然后繼續總結“BREAK”行之后的duration列

即我想得到結果

Sum of Duration
---------------
6.08
3.33

我嘗試了這個語句,但它沒有返回上述期望的結果:

SELECT duration, paycode, visitstart
INTO #client
FROM VISITS
WHERE visitstart > '2020-01-20'
  AND visitstart < '2020-01-21'
  AND paycode <> 'BREAK'
ORDER BY VISITSTART, CLIENT_ID

SELECT SUM(duration) AS total_duration, visitstart, paycode
FROM #client
GROUP BY visitstart, paycode

DROP TABLE #client

請多多指教

試試下面的 - 這是一個gap & island問題

select sum(duration) as total_duration
from
(
select t.*,
       row_number() over (order by visitstart) as seqnum,
       row_number() over (partition by case when paycode='Break' then 1 else 0 end order by visitstart) as seqnumt
from yourtablename t
)A 
where paycode<>'Break'
group by (seqnum-seqnumt)

您可以通過匯總“BREAK”出現的次數來分配組。 然后就可以聚合了。 我不太確定最終持續時間是如何定義的——特別是是否包含“BREAK”行。 假設它是:

select min(visitstart), max(visitstart),
       sum(duration)
from (select t.*,
             sum(case when paycode = 'BREAK' then 1 else 0 end) over (order by visitstart) as grp
      from t
     ) t
where paycode <> 'BREAK'
group by grp

所以,Steve C,我已經盡力幫助你...我做了幾個 cte

  1. cte (cteBreak) - 你只是 select 只是休息。
  2. cte (breaks_chains) - 為每個中斷編號(因為不能使用 row_numbing)
  3. Breaks_chains- 逐對獲取休息時間間隔(例如,第一次休息時間-第二次休息時間,第二次休息時間-第三次休息時間)

注意:如果它是最后一個間隔,那么列 end_break 將被 getdate() 替換,只是為了關閉間隔

  1. 最后我們將我們的表與breaks_chains 組合起來,而不是輸入你的表名

    --just get rows with BREAK paycode with cteBreak as ( select * from Table where paycode='BREAK' ), --numbering breaks (=row_numbering() in later version sql server) breaks_chains as ( select cte1.visitstart visit_st,count(cte2.visitstart)+1 Num from cteBreak cte1 left join cteBreak cte2 on cte1.visitstart>cte2.visitstart group by cte1.visitstart ), --get pairs as "start_break - end_break" break_interval as ( select t1.visit_st begin_break, COALESCE(t2.visit_st,getdate()) as end_break,t1.Num from breaks_chains t1 left join breaks_chains t2 on t2.Num-t1.Num=1 ) select sum(duration) from ( select duration,paycode, case when (Table.visitstart>break_interval.begin_break and Table.visitstart<break_interval.end_break) then break_interval.end_break when (Table.visitstart<break_interval.begin_break and Num=1) then break_interval.begin_break end NumGroup from Table left join break_interval on (Table.visitstart>break_interval.begin_break and Table.visitstart<break_interval.end_break) or (Table.visitstart<break_interval.begin_break and Num=1) --for first sequence (before first break) )t where paycode<>'BREAK' group by NumGroup

PS如果你有問題,請寫在評論中)

暫無
暫無

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

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