我正在尝试在PostgreSQL上构建一个逻辑,将一些信用额度标记为“续订”。 每一行代表一个新的信用额度,续订案例或只是一个术语的变化(金额或利息,我没有在表格中显示为简单),这不被视为续订的信用额度。 将信用额度标记为续订的规则是,在原始信用额度授予日期之后至少80天或之前续订案例之后80天批准。 列'标志'显示了我想要实现的目标。 “1”表示新的信用额度或续订,“0”表示其他情况。我想使用标志来区分哪些信用额度应该用于报告(标记为0的信用额度不应报告)。 在PostgreSQL中最好的方法是什么。
+----------+-----------+-----------------------+--------+------+------+
| customer | date | days_after_first_line | amount | rank | flag |
+----------+-----------+-----------------------+--------+------+------+
| a | 1/1/2015 | 0 | 100 | 1 | 1 |
| a | 2/28/2015 | 58 | 150 | 2 | 0 |
| a | 3/26/2015 | 84 | 150 | 3 | 1 |
| a | 4/6/2015 | 95 | 170 | 4 | 0 |
| a | 6/11/2015 | 161 | 170 | 5 | 0 |
| a | 6/17/2015 | 167 | 200 | 6 | 1 |
| a | 7/14/2015 | 194 | 200 | 7 | 0 |
| a | 9/14/2015 | 256 | 200 | 8 | 1 |
| a | 9/14/2015 | 256 | 200 | 8 | 1 |
| a | 10/5/2015 | 277 | 200 | 9 | 0 |
| b | 1/1/2014 | 0 | 50 | 1 | 1 |
| b | 3/2/2014 | 60 | 50 | 2 | 0 |
| b | 4/1/2014 | 90 | 50 | 3 | 1 |
| b | 6/15/2014 | 165 | 80 | 4 | 0 |
| b | 7/20/2014 | 200 | 80 | 5 | 1 |
+----------+-----------+-----------------------+--------+------+------+
答案 0 :(得分:1)
您可以使用递归查询:
WITH RECURSIVE t(customer, date, days_after_first_line, amount, rank, flag,
new_flag, last_daysafter)
AS(
SELECT customer, date, days_after_first_line, amount, rank, flag,
1 as new_flag, days_after_first_line As last_daysafter
FROM table1
WHERE days_after_first_line = 0
UNION ALL
SELECT t1.customer, t1.date, t1.days_after_first_line, t1.amount, t1.rank, t1.flag,
CASE WHEN t1.days_after_first_line - t.last_daysafter >=80
THEN 1 ELSE 0
END As flag,
CASE WHEN t1.days_after_first_line - t.last_daysafter >=80
THEN t1.days_after_first_line ELSE t.last_daysafter
END As flag
FROM table1 t1
JOIN t ON t1.customer = t.customer AND t.rank + 1 = t1.rank
)
SELECT * FROM t
order by 1,2;
演示:http://sqlfiddle.com/#!15/bb5eb/6
在此演示中(在此查询的结果中)flag
列取自数据,并计算new_flag
列,因此您可以将预期结果与实际(计算的)new_flag
值进行比较。