2016-05-03 88 views
1

我試圖運行一個報表,它將按月對各行中具有以下各列的費用表進行分組總計:在select語句中按月,按月分組值

expense_acc 
debit 
credit 
post_date 

報告的期望輸出是以下列格式: EXP ACC日 - 1月 - 2至3月

這是我的SQL SELECT查詢:

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

[自動生成數據透視碼](http://mysql.rjweb.org/doc.php/pivot) –

回答

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 
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 | 

...

因爲如果你如果每個月發言,你會得到12個ifs。 管理控制器中的行格式會更好。

希望它能幫助你。

1

您有兩部分滿足您的要求。

  1. 一個月按一個月彙總的表格中的內容
  2. 一個透視表渲染,在你轉動的月行位於列。

而且,SUM(expenses.debit-expenses.credit)不是彈性的,如果debitcredit列有史以來包含NULL值。

此外,在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數據透視代碼非常困難。