Mysql SQL查询-按到期月份透视贷款汇总
这看起来很简单,但我正使劲把头撞到墙上想弄明白 我有一个单一的贷款数据表,我想重点分析和总结每个月的付款到期。这类似于“静态池分析”,将每个贷款池作为行,月份作为列。您可以使用以下命令查看示例数据Mysql SQL查询-按到期月份透视贷款汇总,mysql,sql,pivot,Mysql,Sql,Pivot,这看起来很简单,但我正使劲把头撞到墙上想弄明白 我有一个单一的贷款数据表,我想重点分析和总结每个月的付款到期。这类似于“静态池分析”,将每个贷款池作为行,月份作为列。您可以使用以下命令查看示例数据 如果有帮助的话,我已经创建了一个例子来更好地解释我需要的重点和总结结果。谢谢你的帮助 如果不需要是动态的,则使用SUM中的CASE-WHEN或If语句作为MySQL中的枢轴: SELECT PoolMonth, SUM(OriginationAmt) AS Origination, S
如果有帮助的话,我已经创建了一个例子来更好地解释我需要的重点和总结结果。谢谢你的帮助 如果不需要是动态的,则使用SUM中的CASE-WHEN或If语句作为MySQL中的枢轴:
SELECT
PoolMonth,
SUM(OriginationAmt) AS Origination,
SUM(IF(PmtDue = 201512, AmtPaid, 0)) AS `201512`,
SUM(IF(PmtDue BETWEEN 201512 AND 201601, AmtPaid, 0)) AS `201601`,
SUM(IF(PmtDue BETWEEN 201512 AND 201602, AmtPaid, 0)) AS `201602`
FROM
Loans
GROUP BY
PoolMonth;
这有点冗长,无法获取total OriginationAmt、PoolMonth/PmtDue的运行总数,并且只输出最新的运行总数,而不进行任何硬编码,但我们现在开始:-)
从这里开始,在Excel或其他任何地方查看结果都应该非常容易。感谢您花时间回答。是的,这是可行的,但是,正如您所注意到的,我的场景是动态的,PmtDue列中的月份不一样,这就是为什么需要该列上的透视。我将在稍后更新我的答案,但您基本上是在寻找这个:我通常在查询中避免使用动态SQL,因为它很难阅读,而且我通常可以更清楚地将这种动态数据透视移动到应用程序层(Excel、Tableau、Web应用程序等)。我实际上可以使用Excel来透视数据,只要数据可以以同样的方式汇总。Excel将允许我稍后在数据上添加过滤器。这将使您的输出更易于操作,而无需单独指定范围。
SELECT
t.PoolMonth,
t.TtlOriginationAmt,
t.PmtDue,
t.RtAmtPaid
FROM
(
SELECT
l.PoolMonth,
l.OriginationAmt,
orig.TtlOriginationAmt,
l.PmtDue,
/* Row_Number() equivalent for MySQL http://blog.sqlauthority.com/2014/03/09/mysql-reset-row-number-for-each-group-partition-by-row-number/ */
/* Assign a Row Number for each Payment Due month for the individual Pool month in ascending order (ORDER BY clause important in this subquery) */
@RowNumber := CASE WHEN @PoolMonth = l.PoolMonth AND @PmtDue = l.PmtDue THEN @RowNumber + 1 ELSE 1 END AS PoolPmtRowNumber,
/* Use the total count of PmtDue month rows for each PoolMonth so we can limit our results to the final row */
lr.PoolPmtLastRow,
l.AmtPaid,
/* Running total of Amount Paid for the individual Pool month in order of Payment Due month (ORDER BY clause important in this subquery) */
@RtAmtPaid := CASE WHEN @PoolMonth = l.PoolMonth THEN @RtAmtPaid + l.AmtPaid ELSE l.AmtPaid END AS RtAmtPaid,
/* Keep track of the Pool month we're totalling */
@PoolMonth := l.PoolMonth,
/* Keep track of the Payment Due month we're ordering */
@PmtDue := l.PmtDue
FROM
Loans l
JOIN
/* Get the Total Origination Amount */
(SELECT PoolMonth, SUM(OriginationAmt) AS TtlOriginationAmt FROM Loans GROUP BY PoolMonth) orig ON orig.PoolMonth = l.PoolMonth
JOIN
/* Get the total number of records by Pool/Payment due month so we can filter to the last row */
(SELECT PoolMonth, PmtDue, COUNT(1) AS PoolPmtLastRow FROM Loans GROUP BY PoolMonth, PmtDue) AS lr ON lr.PoolMonth = l.PoolMonth AND lr.PmtDue = l.PmtDue
CROSS JOIN
/* Reset the variables we need for tracking */
(SELECT @RtAmtPaid:=0,@PoolMonth:=0,@PmtDue:=0,@RowNumber:=0) var
/* Order by Pool/Payment Due month */
ORDER BY
l.PoolMonth,
l.PmtDue
)t
WHERE
/* Filter to the last row */
t.PoolPmtRowNumber = t.PoolPmtLastRow;