我有以下问题:从工资表中,我需要找到上次逾期的日期。例如,这是表格和数据:
<TouchableOpacity
style={styles.buttonText}
onPress={()=>this.props.navigation.navigate('AirLineSearchResult')}
>
<View style={styles.buttonContainer}>
<Text
style={styles.okBotton}
>جست و جو</Text>
</View>
</TouchableOpacity>
如果“ Sum”的值为正-表示过期已开始;如果“总和”为负数,则表示有人为此交易付款。
在上面关于“ 122222”交易的示例中,逾期从2017年12月13日开始,到2017年12月29日结束,因此不应出现在结果中。
对于“ 222221”交易,始于2017-11-20的第一个25,000的逾期款项已于2017-11-28支付完毕,所以当前逾期(我们感兴趣)的最后日期是2017-12- 31
我已选择此选项以汇总所有付款,并停留在此处:(
create table t (
Id int
, [date] date
, Customer varchar(6)
, Deal varchar(6)
, Currency varchar(3)
, [Sum] int
);
insert into t values
(1, '2017-12-12', '1110', '111111', 'USD', 12000)
, (2, '2017-12-25', '1110', '111111', 'USD', 5000)
, (3, '2017-12-13', '1110', '122222', 'USD', 10000)
, (4, '2018-01-13', '1110', '111111', 'USD', -10100)
, (5, '2017-11-20', '2200', '222221', 'USD', 25000)
, (6, '2017-12-20', '2200', '222221', 'USD', 20000)
, (7, '2017-12-31', '2201', '222221', 'USD', -10000)
, (8, '2017-12-29', '1110', '122222', 'USD', -10000)
, (9, '2017-11-28', '2201', '222221', 'USD', -30000);
如果没有0或负的Debt_balance,显然我需要(对于每个交易)查找最少的Dates,否则,最后一个0余额之后的下一个日期。
对于有关该主题的任何提示和想法将不胜感激。 谢谢!
更新 我的解决方案版本:
WITH cte AS (
SELECT *,
SUM([Sum]) OVER(PARTITION BY Deal ORDER BY [Date]) AS Debt_balance
FROM t
)
答案 0 :(得分:1)
您可以使用窗口功能。这些可以计算中间值:
然后您可以将它们结合起来
select deal, min(date) as last_overdue_start_date
from (select t.*,
first_value(sum) over (partition by deal order by date desc) as last_sum,
max(case when sum < 0 then date end) over (partition by deal order by date) as max_date_neg
from t
) t
where last_sum > 0 and date > max_date_neg
group by deal;
实际上,不需要最后一个日期的值。因此,简化为:
select deal, min(date) as last_overdue_start_date
from (select t.*,
max(case when sum < 0 then date end) over (partition by deal order by date) as max_date_neg
from t
) t
where date > max_date_neg
group by deal;
答案 1 :(得分:1)
我相信您正在尝试使用连续求和并跟踪它何时变为正值,并且它可能多次变为正值,并且您希望它变为正值的最后日期。除了运行总和,您还需要LAG()
:
WITH cte1 AS (
-- running balance column
SELECT *
, SUM([Sum]) OVER (PARTITION BY Deal ORDER BY [Date], Id) AS RunningBalance
FROM t
), cte2 AS (
-- overdue begun column - set whenever running balance changes from l.t.e. zero to g.t. zero
SELECT *
, CASE WHEN LAG(RunningBalance, 1, 0) OVER (PARTITION BY Deal ORDER BY [Date], Id) <= 0 AND RunningBalance > 0 THEN 1 END AS OverdueBegun
FROM cte1
)
-- eliminate groups that are paid i.e. sum = 0
SELECT Deal, MAX(CASE WHEN OverdueBegun = 1 THEN [Date] END) AS RecentOverdueDate
FROM cte2
GROUP BY Deal
HAVING SUM([Sum]) <> 0