2017-04-06 2 views
2

私は自分の請求書に遅れているユーザーのリストを持っています。遅れていた。GROUP BY内で条件を満たす連続したエントリの数をカウントする

user | bill_date | outstanding_balance 
--------------------------------------- 
a | 2017-03-01 |  90 
a | 2016-12-01 |  60 
a | 2016-09-01 |  30 
b | 2017-03-01 |  50 
b | 2016-12-01 |  0 
b | 2016-09-01 |  40 
c | 2017-03-01 |  0 
c | 2016-12-01 |  0 
c | 2016-09-01 |  1 

そして私は、次の表を生成するクエリをしたい:だからここの表です

つまり
user | consecutive_billing_periods_behind 
----------------------------------------- 
    a |    3 
    b |    1 
    a |    0 

、あなたが任意の時点で払込した場合、私はすべて無視したいですあなたが最後に支払ってからあなたが遅れていた請求期間の数だけをカウントします。最も簡単にこれを行うにはどうすればいいですか?

答えて

0

私が正しく質問を理解している場合、最初にあなたが最後の日は彼らの残高が必要ですこのサブクエリによってこれを行うことができます0だったので、任意の顧客が彼らの手形を支払った最後の日付を見つける必要がある:

  (SELECT 
       user1, 
       bill_date AS no_outstanding_bill_date 
      FROM table1 
      WHERE outstanding_balance = 0) 

それから未払いの請求書であれば、最後の請求書日付を取得し、各行のフィールドを作成する必要があります。

WHERE bill_date >= last_clear_day AND bill_date <= last_bill_date 

次にあなたが一緒に作品を置く場合は、このクエリによって結果を持つことができます:

SELECT 
    DISTINCT 
    user1, 
    sum(is_outstanding_bill) 
    OVER (
    PARTITION BY user1) AS consecutive_billing_periods_behind 
FROM (
     SELECT 
     user1, 
     last_value(bill_date) 
     OVER (
      PARTITION BY user1 
      ORDER BY bill_date 
      ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_bill_date, 
     CASE WHEN outstanding_balance > 0 
      THEN 1 
     ELSE 0 END             AS is_outstanding_bill, 
     bill_date, 
     outstanding_balance, 
     nvl(max(t2.no_outstanding_bill_date) 
      OVER (
       PARTITION BY user1), min(bill_date) 
      OVER (
       PARTITION BY user1))         AS last_clear_day 

     FROM table1 t1 
     LEFT JOIN (SELECT 
         user1, 
         bill_date AS no_outstanding_bill_date 
        FROM table1 
        WHERE outstanding_balance = 0) t2 USING (user1) 
    ) table2 
WHERE bill_date >= last_clear_day AND bill_date <= last_bill_date 
その後、このwhere句によって、各顧客の前回の請求日に最後の晴れた日の間で行をフィルタ

distinctを使用しているので、group by句は必要ありません。

0
select 
    user, 
    count(case when min_balance > 0 then 1 end) 
    as consecutive_billing_periods_behind 
from 
(
    select 
    user, 
    min(outstanding_balance) 
     over (partition by user order by bill_date) as min_balance 
    from tbl 
) 
group by user 

または:

select 
    user, 
    count(*) 
    as consecutive_billing_periods_behind 
from 
(
    select 
    user, 
    bill_date, 
    max(case when outstanding_balance = 0 then bill_date) over 
     (partition by user) 
     as max_bill_date_with_zero_balance 
    from tbl 
) 
where 
    -- If user has no outstanding_balance = 0, then 
    max_bill_date_with_zero_balance is null 
    -- Count all rows in this case. 

    -- Otherwise 
    or 
    -- count rows with 
    bill_date > max_bill_date_with_zero_balance 
group by user 
関連する問題