SQL写法(版本1)

SELECTDATE(PAYMENT_DATE),SUM(CASE WHEN PERIOD = 1 AND OVERDUE_LONG > 8 THEN MONTH_CAPITAL ELSE NULL END)/SUM(MONTH_CAPITAL) MOB1, -- MOB1账龄1期SUM(CASE WHEN (PERIOD = 1 AND OVERDUE_LONG > 15) OR (PERIOD = 2 AND OVERDUE_LONG > 8) THEN MONTH_CAPITAL ELSE NULL END)/SUM (MONTH_CAPITAL) MOB2, -- MOB2账龄2期SUM(CASE WHEN (PERIOD = 1 AND OVERDUE_LONG > 22) OR (PERIOD = 2 AND OVERDUE_LONG > 15) OR (PERIOD = 3 AND OVERDUE_LONG > 8) THEN MONTH_CAPITAL ELSE NULL END)/SUM (MONTH_CAPITAL) MOB3, -- M0B3账龄3期SUM(CASE WHEN (PERIOD = 1 AND OVERDUE_LONG > 29) OR (PERIOD = 2 AND OVERDUE_LONG > 22) OR (PERIOD = 3 AND OVERDUE_LONG > 15) OR (PERIOD = 4 AND OVERDUE_LONG > 8) THEN MONTH_CAPITAL ELSE NULL END)/ SUM (MONTH_CAPITAL) MOB4, -- MOB4账龄4期
FROM(SELECT*,CASE WHEN E.REPAY_STATUS = 1 THEN DATEDIFF(DATE(NOW()), DATE (E.REPAY_TIME))WHEN E.REPAY_STATUS = 2 AND REMIND_END_DATE IS NULL THEN 0WHEN E.REPAY_STATUS = 2 AND REMIND_END_DATE IS NOT NULL THEN DATEDIFF(DATE(REMIND_END_DATE), DATE(E.REPAY_TIME)) ELSE NULL END OVERDUE_LONG -- 逾期天数计算FROM (SELECT * FROM BOR.CONTRACT WHERE CREATE_TIME >= '2019-08-01 00:00:00' AND PERIOD = 4) A #合同表LEFT JOIN BOR_INSTALLMENT_PLAN D #还款计划表ON A.APPLY_ID = D.APPLY_IDLEFT JOINHUANKUAN E #实际还款表ON A.APPLY_ID = E.APPLY_ID AND D.PERIOD = E.PERIODLEFT JOIN CUISHOU F #催收表ON A.CONTRACI_ID = F.CONTRACT_ID AND DATE(D.REPAY_TIME) = DATE_ADD(DATE(F.OVERDUE_DATE), INTERVAL - 1 DAY)WHERE B.APPLY = 'DD' -- 产品AND B.FIRST_AGAIN = 2 -- 新户老户AND B.CREATE_TIME >= '2019-06-01 00:00:00' -- 借款时间限制) BB
GROUP BY DATE(PAYMENT_DATE) -- 分组
ORDER BY DATE(PAYMENT_DATE) -- 排序;

SQL写法(版本2)

先建一个month表,明确月末时间点。

-- Create table `months`
--
CREATE TABLE months (num int(11) NOT NULL,yyyymm varchar(20) DEFAULT NULL,start_datetime datetime DEFAULT NULL,end_datetime datetime DEFAULT NULL,PRIMARY KEY (num)
)
ENGINE = INNODB,
AVG_ROW_LENGTH = 80,
CHARACTER SET utf8mb4,
COLLATE utf8mb4_general_ci;--
-- Create index `idx_end_datetime` on table `months`
--
ALTER TABLE months
ADD UNIQUE INDEX idx_end_datetime (end_datetime);--
-- Create index `idx_start_datetime` on table `months`
--
ALTER TABLE months
ADD UNIQUE INDEX idx_start_datetime (start_datetime);--
-- Create index `idx_yyyymm` on table `months`
--
ALTER TABLE months
ADD UNIQUE INDEX idx_yyyymm (yyyymm);INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(61, '2019/01', '2019-01-01 00:00:00', '2019-01-31 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(62, '2019/02', '2019-02-01 00:00:00', '2019-02-28 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(63, '2019/03', '2019-03-01 00:00:00', '2019-03-31 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(64, '2019/04', '2019-04-01 00:00:00', '2019-04-30 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(65, '2019/05', '2019-05-01 00:00:00', '2019-05-31 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(66, '2019/06', '2019-06-01 00:00:00', '2019-06-30 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(67, '2019/07', '2019-07-01 00:00:00', '2019-07-31 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(68, '2019/08', '2019-08-01 00:00:00', '2019-08-31 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(69, '2019/09', '2019-09-01 00:00:00', '2019-09-30 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(70, '2019/10', '2019-10-01 00:00:00', '2019-10-31 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(71, '2019/11', '2019-11-01 00:00:00', '2019-11-30 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(72, '2019/12', '2019-12-01 00:00:00', '2019-12-31 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(73, '2020/01', '2020-01-01 00:00:00', '2020-01-31 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(74, '2020/02', '2020-02-01 00:00:00', '2020-02-29 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(75, '2020/03', '2020-03-01 00:00:00', '2020-03-31 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(76, '2020/04', '2020-04-01 00:00:00', '2020-04-30 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(77, '2020/05', '2020-05-01 00:00:00', '2020-05-31 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(78, '2020/06', '2020-06-01 00:00:00', '2020-06-30 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(79, '2020/07', '2020-07-01 00:00:00', '2020-07-31 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(80, '2020/08', '2020-08-01 00:00:00', '2020-08-31 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(81, '2020/09', '2020-09-01 00:00:00', '2020-09-30 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(82, '2020/10', '2020-10-01 00:00:00', '2020-10-31 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(83, '2020/11', '2020-11-01 00:00:00', '2020-11-30 23:59:59');
INSERT INTO months(num, yyyymm, start_datetime, end_datetime) VALUES(84, '2020/12', '2020-12-01 00:00:00', '2020-12-31 23:59:59');

再进入正题。

SELECTm.yyyymm                                                                                                                                                                                                                                                                                                                                                                                                                                      AS '放款年月',SUM(lrp.receivable_principal)                                                                                                                                                                                                                                                                                                                                                                                                                 AS '放款本金',COUNT(lrp.id)                                                                                                                                                                                                                                                                                                                                                                                                                                 AS '放款对应还款计划数',COUNT(DISTINCT lrp.user_id)                                                                                                                                                                                                                                                                                                                                                                                                                   AS '放款对应用户数',PERIOD_DIFF(DATE_FORMAT(STR_TO_DATE(m_after.yyyymm, '%Y/%m'), '%Y%m'), DATE_FORMAT(STR_TO_DATE(m.yyyymm, '%Y/%m'), '%Y%m'))                                                                                                                                                                                                                                                                                                                   AS '后续年月序号',m_after.yyyymm                                                                                                                                                                                                                                                                                                                                                                                                                                AS '后续年月',SUM(IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), lrp.receivable_principal, 0))                                                                                                                                                                                                                                                                                                                 AS '累计应收本金',SUM(IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), 1, 0))                                                                                                                                                                                                                                                                                                                                        AS '累计应收还款计划数',COUNT(DISTINCT IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), lrp.user_id, NULL))                                                                                                                                                                                                                                                                                                                AS '累计应收用户数',SUM(IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 >= 1, lrp.receivable_principal, 0))                 AS '累计逾期本金',SUM(IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 >= 1, 1, 0))                                        AS '累计逾期还款计划数',COUNT(DISTINCT IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 >= 1, lrp.user_id, NULL))                AS '累计逾期还款用户数',SUM(IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 BETWEEN 1 AND 3, lrp.receivable_principal, 0))      AS '累计逾期本金(1-3)',SUM(IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 BETWEEN 1 AND 3, 1, 0))                             AS '累计逾期还款计划数(1-3)',COUNT(DISTINCT IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 BETWEEN 1 AND 3, lrp.user_id, NULL))     AS '累计逾期还款用户数(1-3)',SUM(IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 BETWEEN 1 AND 30, lrp.receivable_principal, 0))     AS '累计逾期本金(1-30)',SUM(IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 BETWEEN 1 AND 30, 1, 0))                            AS '累计逾期还款计划数(1-30)',COUNT(DISTINCT IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 BETWEEN 1 AND 30, lrp.user_id, NULL))    AS '累计逾期还款用户数(1-30)',SUM(IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 BETWEEN 31 AND 60, lrp.receivable_principal, 0))    AS '累计逾期本金(31-60)',SUM(IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 BETWEEN 31 AND 60, 1, 0))                           AS '累计逾期还款计划数(31-60)',COUNT(DISTINCT IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 BETWEEN 31 AND 60, lrp.user_id, NULL))   AS '累计逾期还款用户数(31-60)',SUM(IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 BETWEEN 61 AND 90, lrp.receivable_principal, 0))    AS '累计逾期本金(61-90)',SUM(IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 BETWEEN 61 AND 90, 1, 0))                           AS '累计逾期还款计划数(61-90)',COUNT(DISTINCT IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 BETWEEN 61 AND 90, lrp.user_id, NULL))   AS '累计逾期还款用户数(61-90)',SUM(IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 BETWEEN 91 AND 120, lrp.receivable_principal, 0))   AS '累计逾期本金(91-120)',SUM(IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 BETWEEN 91 AND 120, 1, 0))                          AS '累计逾期还款计划数(91-120)',COUNT(DISTINCT IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 BETWEEN 91 AND 120, lrp.user_id, NULL))  AS '累计逾期还款用户数(91-120)',SUM(IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 BETWEEN 121 AND 150, lrp.receivable_principal, 0))  AS '累计逾期本金(121-150)',SUM(IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 BETWEEN 121 AND 150, 1, 0))                         AS '累计逾期还款计划数(121-150)',COUNT(DISTINCT IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 BETWEEN 121 AND 150, lrp.user_id, NULL)) AS '累计逾期还款用户数(121-150)',SUM(IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 BETWEEN 151 AND 180, lrp.receivable_principal, 0))  AS '累计逾期本金(151-180)',SUM(IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 BETWEEN 151 AND 180, 1, 0))                         AS '累计逾期还款计划数(151-180)',COUNT(DISTINCT IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 BETWEEN 151 AND 180, lrp.user_id, NULL)) AS '累计逾期还款用户数(151-180)',SUM(IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 > 180, lrp.receivable_principal, 0))                AS '累计逾期本金(>180)',SUM(IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 > 180, 1, 0))                                       AS '累计逾期本金还款计划数(>180)',COUNT(DISTINCT IF(lrp.repayment_due_date <= IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime) AND lrp.repayment_status IN (4, 5, 6) AND DATEDIFF(IF(lrp.repayment_date IS NULL OR lrp.repayment_date > IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), IF(NOW() < m_after.end_datetime, NOW(), m_after.end_datetime), '2000/01/01 23:59:59'), lrp.repayment_due_date) + 1 > 180, lrp.user_id, NULL))               AS '累计逾期本金还款用户数(>180)'
FROM p2p_system.months mJOIN p2p_system.months m_afterON m_after.yyyymm >= m.yyyymmAND m_after.yyyymm <= '${QUERY_MONTH}'JOIN p2p_loan.loan_contract lcON lc.isdel = 0AND lc.contract_status IN (19, 7, 8, 9, 10)AND lc.contract_transfer_time >= m.start_datetimeAND lc.contract_transfer_time <= m.end_datetime${IF(len(repayment_type)==0,"","AND lc.repayment_type = "+repayment_type)}${IF(len(term_month)==0,"","AND lc.term_month IN("+term_month+")")}${IF(len(term_day)==0,"","AND lc.term_day IN("+term_day+")")}
${IF(len(channel)==0,"","AND (CASE WHEN lc.channel = '###' THEN '###' END) IN("+channel+")")}JOIN p2p_loan.loan_repayment_plan lrpON lrp.isdel = 0AND lrp.contract_number = lc.contract_number
WHERE m.yyyymm >= '${BEGIN_MONTH}'
AND m.yyyymm <= '${END_MONTH}'
GROUP BY m.yyyymm,m_after.yyyymm
ORDER BY m.yyyymm,
m_after.yyyymm

python写法

import numpy as np
import pandas as pdfrom monitor.commons.dateProcessing import Date
from monitor.commons.myThread import myThread, ALL_COMPLETED, wait
from monitor.commons.oralceClient import *
from monitor.commons.tools_02 import getApplyDataSQL, getOverduedaysInfoSqlAll, getLoanDataOfNoID, getLoanDataSqlALL, \getScheduleDataSQLAlldef dataSave(sql_str):# 大航旅业务库dhl_user = ""dhl_passwd = ""dhl_url = ""dhl_db, dhl_cursor = oracleConnect(dhl_user, dhl_passwd, dhl_url)dd = pd.read_sql(sql_str, dhl_db)return dddef getVintageIndex(startDate, endDate):"""获取行索引(按月):param startDate: 开始时间:param endDate: 结束时间:return: 行索引、时间范围"""date_end = Date.date_range(startDate, endDate, freq="m")date_start = [Date.first_day_of_month(x) for x in date_end]date_range = list(zip(date_start, date_end))dateIndex = [date_range[i][0].strftime("%Y-%m") for i in range(len(date_range))]return dateIndex, date_rangedef getVintageMobDate(startDate, endDate):"""获取Vintage的账龄(mob)区间:param startDate: 开始时间:param endDate: 结束时间:return: 账龄名,账龄区间"""date_end = Date.date_range(startDate, endDate, freq="m")date_start = [Date.first_day_of_month(x) for x in date_end]date_range = list(zip(date_start, date_end))colName = ["MOB_%s" % i for i in range(len(date_range))]return colName, date_rangedef getApplyData(apply_startDate, apply_endDate, productid):# 获取申请信息sql_str = getApplyDataSQL(apply_startDate, apply_endDate, productid)dataApplyData = pd.read_sql(sql_str, dhl_db)dataApplyData['SERIALNO'] = dataApplyData['SERIALNO'].astype('str')return dataApplyDatadef getLoanData(IDList, putout_startDate, putout_endDate, productId=""):# 获取借据信息if len(IDList) == 0:loanDataSql = getLoanDataOfNoID(putout_startDate, putout_endDate, productId)loanDataSqlALL = [loanDataSql]else:loanDataSqlALL = getLoanDataSqlALL(IDList, putout_startDate, putout_endDate)loanDataInfo = [pd.read_sql(sql_str, dhl_db) for sql_str in loanDataSqlALL]loanDataInfo = pd.concat(loanDataInfo)loanDataInfo['SERIALNO'] = loanDataInfo['SERIALNO'].astype('str')return loanDataInfo# 获取还款计划
def getScheduleData(IDList):"""获取还款记录:param IDList: 通过贷款(动支)ID获取还款记录:return: 还款记录表"""IDList = [str(x) for x in IDList]filedkey = 'serialno'sql_str_all = getScheduleDataSQLAll(IDList, filedkey, max_length=5000)mt = myThread(max_workers=10)all_task = [mt.run(dataSave, sql_str) for sql_str in sql_str_all]wait(all_task, return_when=ALL_COMPLETED)data_list = [tt.result() for tt in all_task]data_user_schedual = pd.concat(data_list)return data_user_schedualdef getOverduedaysInfo(IDList, observationDate):"""从日切表中获取逾期天数日切表:数据日备份表(每日数据备份):param IDList: 贷款(动支)ID列表:param observationDate: 观察日:return: 逾期情况表"""fieldKey = "serialno"data_overduedays_sql = getOverduedaysInfoSqlAll(IDList, fieldKey, observationDate)data_overduedays_list = [pd.read_sql(sql_str, sc_db) for sql_str in data_overduedays_sql]data_overduedays = pd.concat(data_overduedays_list)data_overduedays['LOAN_SERIALNO'] = data_overduedays['LOAN_SERIALNO'].astype("str")return data_overduedaysdef getVintageOfUser(dataBase, dataScheduleAll, putout_startDate, putout_endDate, observationDate, overdueDays):"""用户级的vintage表从还款计划中获取逾期人数与逾期天数:param dataBase: 动支信息表:param dataScheduleAll: 还款计划表:param putout_startDate: 动支开始时间:param putout_endDate: 动支结束时间:param observationDate: 观察时间点(vintage表的观察时间点):param overdueDays: 逾期天数(vintage dpd_n+):return:"""dataBase['PUTOUTDATE'] = pd.to_datetime(dataBase['PUTOUTDATE'])dateIndex, date_range = getVintageIndex(putout_startDate, putout_endDate)vintageName_all, mobRange_all = getVintageMobDate(putout_startDate, observationDate)VintageOfUser = pd.DataFrame(None, columns=vintageName_all, index=dateIndex)for i in range(len(date_range)):PutOutStartDate, PutOutEndDate = date_range[i]Index = dateIndex[i]part_dataBase = dataBase[(dataBase['PUTOUTDATE'] >= PutOutStartDate) & (dataBase['PUTOUTDATE'] <= PutOutEndDate)]part_Schedule = dataScheduleAll[dataScheduleAll['LOAN_SERIALNO'].isin(part_dataBase['LOAN_SERIALNO'])].reset_index(drop=True)part_vintageName, part_mobRange = getVintageMobDate(PutOutStartDate, observationDate)for j in range(len(part_vintageName)):mob_name = part_vintageName[j]part_PutOutStartDate, part_PutOutEndDate = part_mobRange[j]# 获取逾期天数(从还款计划中获取逾期天数)part_Schedule_01 = part_Schedule[(part_Schedule['PAYDATE'] <= part_PutOutEndDate)].reset_index(drop=True)part_Schedule_01['ACTUALPAYDATE'] = pd.to_datetime(part_Schedule_01['ACTUALPAYDATE'])part_Schedule_01['ACTUALPAYDATE'] = part_Schedule_01['ACTUALPAYDATE'].apply(lambda x: part_PutOutEndDate if (pd.isna(x)) | (x > part_PutOutEndDate) else x)part_Schedule_01['PAYDATE'] = pd.to_datetime(part_Schedule_01['PAYDATE'])part_Schedule_01['OVERDUEDAYS'] = (part_Schedule_01['ACTUALPAYDATE'] - part_Schedule_01['PAYDATE']).dt.days + 1part_overdueData = part_Schedule_01[part_Schedule_01["OVERDUEDAYS"] > overdueDays]part_overdueData_01 = part_dataBase[part_dataBase["LOAN_SERIALNO"].isin(part_overdueData["LOAN_SERIALNO"])]UserNum = part_dataBase['CUSTOMERID'].nunique()overdueUserNum = part_overdueData_01['CUSTOMERID'].nunique()overdueRotio = round(overdueUserNum / UserNum, 4) if UserNum > 0 else 0VintageOfUser.loc[Index, mob_name] = overdueRotioreturn VintageOfUserdef getVintageOfAmount(dataBase, putout_startDate, putout_endDate, observationEndDate, overdueDays):"""金额级的Vintage表;从日切表中获取逾期金额与逾期天数:param dataBase: 动支信息表:param putout_startDate: 动支开始时间:param putout_endDate: 动支结束时间:param observationEndDate: 观察时间点(vintage表的观察时间点):param overdueDays: 逾期天数(vintage dpd_n+):return:"""dataBase['PUTOUTDATE'] = pd.to_datetime(dataBase['PUTOUTDATE'])dateIndex, date_range = getVintageIndex(putout_startDate, putout_endDate)vintageName_all, mobRange_all = getVintageMobDate(putout_startDate, observationEndDate)VintageOfAmount = pd.DataFrame(None, columns=vintageName_all, index=dateIndex)for i in range(len(date_range)):PutOutStartDate, PutOutEndDate = date_range[i]Index = dateIndex[i]part_dataBase = dataBase[(dataBase['PUTOUTDATE'] >= PutOutStartDate) & (dataBase['PUTOUTDATE'] <= PutOutEndDate)]IDList = list(part_dataBase['LOAN_SERIALNO'].unique())part_vintageName, part_mobRange = getVintageMobDate(PutOutStartDate, observationEndDate)for j in range(len(part_vintageName)):# print(i, j)mob_name = part_vintageName[j]part_PutOutStartDate, part_PutOutEndDate = part_mobRange[j]part_obserivationDate = part_PutOutEndDate.strftime("%Y%m%d")# 获取逾期天数(从日切表中获取逾期金额、逾期天数)part_overdueData = getOverduedaysInfo(IDList, part_obserivationDate)part_overdueData.drop_duplicates(inplace=True)LoanAmount = part_dataBase[['LOAN_SERIALNO', "DZ_SUM"]].drop_duplicates()['DZ_SUM'].sum()overdueUserNum = part_overdueData[part_overdueData["OVERDUEDAYS"] > overdueDays][['NORMALBALANCE', 'OVERDUEBALANCE']].sum(skipna=True).sum(skipna=True)overdueRotio = round(overdueUserNum / LoanAmount, 4) if LoanAmount > 0 else 0VintageOfAmount.loc[Index, mob_name] = overdueRotioreturn VintageOfAmountdef getVintageOfUser_01(dataBase, putout_startDate, putout_endDate, observationDate, overdueDays):dataBase['PUTOUTDATE'] = pd.to_datetime(dataBase['PUTOUTDATE'])dateIndex, date_range = getVintageIndex(putout_startDate, putout_endDate)vintageName_all, mobRange_all = getVintageMobDate(putout_startDate, observationDate)VintageOfUser = pd.DataFrame(None, columns=vintageName_all, index=dateIndex)for i in range(len(date_range)):PutOutStartDate, PutOutEndDate = date_range[i]Index = dateIndex[i]part_dataBase = dataBase[(dataBase['PUTOUTDATE'] >= PutOutStartDate) & (dataBase['PUTOUTDATE'] <= PutOutEndDate)]IDList = list(part_dataBase['LOAN_SERIALNO'].unique())part_vintageName, part_mobRange = getVintageMobDate(PutOutStartDate, observationDate)for j in range(len(part_vintageName)):mob_name = part_vintageName[j]part_PutOutStartDate, part_PutOutEndDate = part_mobRange[j]part_obserivationDate = part_PutOutEndDate.strftime("%Y%m%d")part_overdueData = getOverduedaysInfo(IDList, part_obserivationDate)part_overdueData['LOAN_SERIALNO'] = part_overdueData['LOAN_SERIALNO'].astype("str")part_overdueData.drop_duplicates(inplace=True)LoanUserNum = part_dataBase["CUSTOMERID"].nunique()LoanOverdueUserNum = part_dataBase[part_dataBase["LOAN_SERIALNO"].isin(part_overdueData[part_overdueData["MAXOVERDUEDAYS"] > overdueDays]['LOAN_SERIALNO'].unique())]["CUSTOMERID"].nunique()overdueRotio = round(LoanOverdueUserNum / LoanUserNum, 4) if LoanUserNum > 0 else 0VintageOfUser.loc[Index, mob_name] = overdueRotioreturn VintageOfUserif __name__ == '__main__':apply_startDate = "2020/07/01"apply_endDate = "2020/11/01"putout_startDate = "2020/07/01"putout_endDate = "2020/11/20"observationDate = "2021/03/01"overdueDays = 14dataBase = getApplyData(apply_startDate, apply_endDate, "HLDXC01")dataBase['SERIALNO'] = dataBase['SERIALNO'].astype("str")dataBase['SF_NO'] = dataBase['SF_NO'].astype("str")dataBase = dataBase[dataBase['APPROVESTATUS'] == '13']IDList = list(dataBase['SERIALNO'].unique())dataLoan = getLoanData(IDList, putout_startDate, putout_endDate)dataLoan['LOAN_SERIALNO'] = dataLoan['LOAN_SERIALNO'].astype("str")dataLoan['SERIALNO'] = dataLoan['SERIALNO'].astype("str")dataLoan = dataLoan[dataLoan['DZ_SUM'] > 0]dataBaseAll = pd.merge(dataBase, dataLoan, on="SERIALNO", how="left")IDList = list(dataLoan['LOAN_SERIALNO'].unique())data_Schedule = getScheduleData(IDList)data_Schedule['LOAN_SERIALNO'] = data_Schedule['LOAN_SERIALNO'].astype("str")data_Schedule['PAYDATE'] = pd.to_datetime(data_Schedule['PAYDATE'])data_Schedule = data_Schedule[data_Schedule['PAYDATE'] <= pd.to_datetime("2021-03-01")].reset_index(drop=True)data_Schedule['ACTUALPAYDATE'] = data_Schedule[['FINISHDATE', 'ACTUALPAYDATE']].apply(lambda x: x[1] if ~np.equal(pd.isna(x[1]), True) else x[0], axis=1)VintageOfUser = getVintageOfUser(dataBaseAll, data_Schedule, putout_startDate, putout_endDate, observationDate,overdueDays)VintageOfUser_01 = getVintageOfUser_01(dataBaseAll, putout_startDate, putout_endDate, observationDate,overdueDays)

Vintage表的写法(sql/python)相关推荐

  1. Oracle和sql server中复制表结构和表数据的sql语句

    在Oracle和sql server中,如何从一个已知的旧表,来复制新生成一个新的表,如果要复制旧表结构和表数据,对应的sql语句该如何写呢?刚好阿堂这两天用到了,就顺便把它收集汇总一下,供朋友们参考 ...

  2. SQL多表查询:SQL JOIN连接查询各种用法总结

    在实际应用中,大多的查询都是需要多表连接查询的,但很多初学SQL的小伙伴总对各种JOIN有些迷糊.回想一下,初期很长一段时间,我常用的似乎也就是等值连接 WHERE 后面加等号,对各种JOIN也是不求 ...

  3. 28_数据库_第28天(数据库、表及表数据、SQL语句)_讲义

    今日内容介绍 1.MySQL数据库 2.SQL语句 01 数据库概念 A: 什么是数据库 数据库就是存储数据的仓库,其本质是一个文件系统,数据按照特定的格式将数据存储起来,用户可以对数据库中的数据进行 ...

  4. Mybatis-Plus一个新的报错:数据库表名与SQL的关键字冲突!!!

    Mybatis-Plus一个新的报错:数据库表名与SQL的关键字冲突!!! 老规矩先上报错信息: 2021-08-27 19:18:19.510 ERROR 33476 --- [nio-9000-e ...

  5. db2 删除schema中所有表_常用SQL系列之(六):删除方式、数据库、表及索引元信息查询等...

    本系统为@牛旦教育IT课堂在微头条上的内容, 为便于查阅,特辑录于此,都是常用SQL基本用法.. 前两篇连接: (一):SQL点滴(查询篇):数据库基础查询案例实战 (二):SQL点滴(排序篇):数据 ...

  6. oracle如何复制dept,[oracle]表复制的sql语句

    oracle复制表sql 可以复制表的结构,也可以复制查询结果,有的时候需要小表,这样比较方面. 使用环境: oracle 10.2 ;scott  的dept表 表结构: SQL> desc ...

  7. JEPaas代码(SQL功能表)通过SQL功能表进行表查询

    JEPaas代码(SQL功能表)通过SQL功能表进行表查询 1.新建一个表单--添加功能表--在功能表配置信息中///如下: 输入相应的SQL查询语句"(在那之前通过SQLserver查询语 ...

  8. mysql 碎片率_计算MySQL表碎片的SQL整理

    原标题:计算MySQL表碎片的SQL整理 这是学习笔记的第 2111 篇文章 在之前整理过一版MySQL的数据字典,整理了一圈,发现远比想象的复杂. 当然整理的过程不光是知识梳理的过程,也是转化为实践 ...

  9. iBatis 事务控制 与 两表操作将SQL语句写入单表

    事务控制 示例: // move data from temp_table to work_tabletry {sqlMapClient.startTransaction();T03SlipWk or ...

最新文章

  1. 倒排索引统计与 Python 字典
  2. java中程序执行顺序
  3. 使用echarts3实现散点地图
  4. java一览删除一条数据_可以删除单条数据,不能再返回列表页面,我使用的是Spring MVC...
  5. 【UFBA Practice Session for Brazilian ICPC Regionals - 2018】Carnival【强连通图求“关键边”】
  6. 给信号添加指定信噪比的带限白噪声
  7. POJ-3744 Scout YYF I 概率DP
  8. 2种方式!带你快速实现前端截图
  9. Design contains shelved or modified (but not repoured) polygons. The result of DRC is not correct.
  10. 用Notepad++ 宏功能 将json数据转换为EXCEL
  11. SN74LS00N芯片逻辑输出电平
  12. 一周消息树:推低端iPhone,将会是苹果必然之举
  13. UG二次开发GRIP创建注释
  14. TIOBE 3 月编程语言排行榜刚刚出炉
  15. 【智能制造】周宏仁:智能制造的三个支点;全球制造业新趋势
  16. 在Kali 2022.2上成功编译驱动TP-LINK TL-WN726免驱版无线USB网卡 8188GU
  17. 坦克大战类型 坦克WASD前后左右移动的解决方法
  18. “金九银十”求职指南:这些城市和行业最热门!
  19. 未来广播电视新技术的发展和应用
  20. [原创]看GONZO《最终兵器彼女》的感想

热门文章

  1. IC卡探索记录- MFRC522+STM32F103C8 操作IC卡(M1卡) ---附代码
  2. Linux——访问网络附加存储
  3. PHP面向对象继承的概念
  4. springcloud坑之 org.springframework.web.client.HttpServerErrorException$InternalServerError: 500 null
  5. 前端自动化测试(一)
  6. es5/es6 继承总结
  7. 关于word转pdf我找到的 最简单的解决方法
  8. 新浪合并分众户外数字广告业务
  9. kswapd0病毒处理
  10. 科大讯飞2014届实习生招聘笔试题