计算付款破损

时间:2014-03-21 12:19:13

标签: sql-server-2008 cursor except

我目前正在制作一份报告,强调付款破损,这是基于客户在6月付款,但后来却未能在7月付款。

我目前已将其设置为执行除查询,检查一个月并将其与下一个进行比较。与下面类似(语法我不正确,因为我不得不编辑某些数据)。

DECLARE @StartDatePaid AS DATETIME
DECLARE @EndDatePaid AS DATETIME
DECLARE @StartDateMissed AS DATETIME
DECLARE @EndDateMissed AS DATETIME

SET @StartDatePaid = '01-Oct-2013'
SET @EndDatePaid   = '31-Oct-2013'
SET @StartDateMissed = '01-Nov-2013'
SET @EndDateMissed = '05-Dec-2013'

SELECT        d.StoreNo   
                , d.CustNo
FROM (
--Paid Range
SELECT     c.CustNo, m.StoreNo 
FROM         dbo.tblCont AS c INNER JOIN
                      dbo.tblContDep AS cd ON c.ContractNo = cd.ContractNo INNER JOIN
                      dbo.tblCust AS m ON c.CustNo = m.CustNo INNER JOIN
                      dbo.tblTrans AS mx ON m.CustNo = mx.CustNo AND cd.AgendaCode = mx.AgendaCode INNER JOIN
                      dbo.tblCalender AS cl ON mx.DateEvent  = cl.Date 
WHERE     (cd.Payment > 0) AND (m.Closed <> 'Y') AND (cd.AgendaCode <> 'OPCLIPMT')
                                 AND mx.DateEvent BETWEEN @StartDatePaid AND @EndDatePaid 
GROUP BY c.CustNo, m.StoreNo, mx.DateEvent 
EXCEPT 
--Missed Range
SELECT     c.CustNo, m.StoreNo
FROM         dbo.tblCont AS c INNER JOIN
                      dbo.tblContDep AS cd ON c.ContractNo = cd.ContractNo INNER JOIN
                      dbo.tblCust AS m ON c.CustNo = m.CustNo INNER JOIN
                      dbo.tblTrans AS mx ON m.CustNo = mx.CustNo AND cd.AgendaCode = mx.AgendaCode INNER JOIN
                      dtLookups.dbo.tblCalender AS cl ON mx.DateEvent = cl.Date 
WHERE     (cd.Payment > 0) AND (m.Closed <> 'Y') AND (cd.AgendaCode <> 'OPCLIPMT') AND (mx.DateEvent BETWEEN @StartDateMissed AND @EndDateMissed )
GROUP BY c.CustNo, m.StoreNo, mx.DateEvent
      ) AS d 
      WHERE d.StoreNo IN (72, 114, 121, 139, 185, 241, 266)
      GROUP BY 
                      d.StoreNo, d.CustNo

我将基于日历月而不是日期范围将其切换,我的问题是如何最好一次产生几个月的破损。为了在一个月的比较中获得一个月,因为它是我只能根据提供的数据创建一个月的破损。

所需输出的示例

Month| breakges
June | 201
July | 189
Aug  | 250

对最佳实践的建议或改进方法持开放态度。

1 个答案:

答案 0 :(得分:0)

我承认我不理解您的查询。假设您的破损是第一次发生缺失付款,而不是后续付款。您可以像这样生成所需的输出:

-- prepare your source data
with cte1 as
(
  select 
    user_id, 
    date, -- representing month by the first day
    missed -- bool flag if payment was missed in that month
    from ...    
)
-- add a sequence number to the source data ordered by date
with cte2 as
(
  select *,
    row_number() over(partition by user_id order by date) rn
  from cte1
)
-- select those records where payment was missed but the previous was ok
,cte3 as
(
  select user_id, date from cte2 a
  where a.missed = 1
  and exists (
    select * from cte2 b 
    where b.missed = 0
    and b.uid = a.uid 
    and b.rn = a.rn -1
    )
)
select date, count(*) as breakage from cte3 group by date