我正在尝试运行一个报表,该报表将按费用表格逐月分组费用帐户的总计,每个行包含以下列:
expense_acc
debit
credit
post_date
报告的所需输出采用以下列格式: EXP ACC - JAN - FEB - MAR
这是我的SQL选择查询:
SELECT expense_acc,
if(MONTH(post_date)=1,SUM(expenses.debit-expenses.credit),0) AS 'JAN',
if(MONTH(post_date)=2,SUM(debit-credit),0) AS 'FEB',
if(MONTH(post_date)=3,SUM(debit-credit),0) AS 'MAR'
FROM expenses
WHERE YEAR(expenses.entered)='2016'
GROUP BY expenses.expense_acc
结果不按预期按月对费用值进行分组。无论交易日期如何,我都会在第一行看到分组。
答案 0 :(得分:1)
根据您的要求,您有两个部分。
此外,如果SUM(expenses.debit-expenses.credit)
或debit
列包含credit
值,则NULL
不具备弹性。
此外,YEAR(date)
会使date
上的任何索引失败。
如果您明智,您将分两步处理这些要求。首先,对结果进行故障排除会更容易。另一方面,下一个出席的人将更好地了解您的项目。
逐月汇总:
SELECT expense_acc, LAST_DAY(post_date) month_ending,
SUM(expenses.debit) - SUM(expenses.credit) as net_expenses
FROM expenses
WHERE post_date >= '2016-01-01'
AND post_date < '20016-12-31' + INTERVAL 1 DAY
GROUP BY expense_acc, LAST_DAY(post_date)
ORDER BY expense_acc, LAST_DAY(post_date)
这会为每个帐户和日期提供一行。该行将显示帐户,月末日期和净费用。 (我不明白你的例子中expenses.entered
。最好在你用来制作聚合的同一天过滤。)你的审计员会理解这种逻辑分离。
接下来,您可以将其用作子查询,以显示枢轴。
这很简单:
SELECT expense_acc,
SUM(IF(MONTH(month_ending)=1,net_expenses,0)) as jan,
SUM(IF(MONTH(month_ending)=2,net_expenses,0)) as feb,
SUM(IF(MONTH(month_ending)=3,net_expenses,0)) as mar,
...
FROM (
SELECT expense_acc, LAST_DAY(post_date) month_ending,
SUM(expenses.debit) - SUM(expenses.credit) as net_expenses
FROM expenses
WHERE post_date >= '2016-01-01'
AND post_date < '20016-12-31' + INTERVAL 1 DAY
) z
GROUP BY expense_acc
ORDER BY expense_acc
但是,您可能希望在客户端程序中进行透视。编写和维护MySQL数据透视代码非常困难。
答案 1 :(得分:0)
SELECT
SUM(JAN) AS JAN,
SUM(FEB) AS FEB
SUM(MAR) AS MAR
FROM
(
SELECT expense_acc,
if(MONTH(post_date)=1,SUM(expenses.debit-expenses.credit),0) AS 'JAN',
if(MONTH(post_date)=2,SUM(debit-credit),0) AS 'FEB',
if(MONTH(post_date)=3,SUM(debit-credit),0) AS 'MAR'
FROM expenses
WHERE YEAR(expenses.entered)='2016'
GROUP BY expenses.expense_acc
)TMP
GROUP BY expense_acc
答案 2 :(得分:0)
在我看来,最佳方式是:
SELECT expense_acc, MONTH(post_date) month_num, SUM(debit-credit) as total
FROM expenses
WHERE YEAR(expenses.entered) = '2016'
GROUP BY expenses.expense_account, MONTH(post_date)
这会给你类似的东西
|expense account | mont_num | total |
-----------------------------------------
| 2345 | 1 | 50 |
-----------------------------------------
| 2345 | 2 | 30 |
-----------------------------------------
| 2346 | 1 | 45 |
...
因为如果你每月做一个if语句,你会得到12个ifs。 管理控制器中的行格式会更好。
希望它会对你有所帮助。