我正在尝试创建一个查询,以获取基于月份的最近12个月的图表表示。经过大量阅读并在看完similar topic之后,我创建了一个看起来正确的查询,但错过了0个月的月份。举个例子,我在图表中看到了1 / 14,2 / 14,4 / 14,等等...... 3/14缺失了。
我的代码就是这个
SELECT *
FROM
(SELECT DATE_FORMAT(now(), '%m/%y') AS Month
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 1 MONTH), '%m/%y')
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 2 MONTH), '%m/%y')
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 3 MONTH), '%m/%y')
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 4 MONTH), '%m/%y')
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 5 MONTH), '%m/%y')
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 6 MONTH), '%m/%y')
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 7 MONTH), '%m/%y')
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 8 MONTH), '%m/%y')
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 9 MONTH), '%m/%y')
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 10 MONTH), '%m/%y')
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 11 MONTH), '%m/%y')
) AS Months
LEFT JOIN
(SELECT sum(expenses.price) AS ExpenseAmount,
sum(payments.amount) AS PaymentsAmount,
DATE_FORMAT(expenses.date_occurred,'%m/%y') AS Month,
DATE_FORMAT(payments.date_occurred,'%m/%y') AS Montha
FROM expenses,
payments
WHERE payments.user_id= 1
AND payments.user_id=expenses.user_id
GROUP BY MONTH(payments.date_occurred),
YEAR(payments.date_occurred)
ORDER BY payments.date_occurred ASC ) data ON Months.MONTH = data.Montha
ORDER BY data.Montha;
任何帮助都会很棒,因为这种查询对我来说太先进了: - )
答案 0 :(得分:1)
由于查询看起来应该为每个月生成一行,您是否可以检查查询输出,而不是图表生成的内容?我怀疑你有一个04/14的条目,但是该值是NULL而不是0.要纠正这个,你可以改变查询开始
SELECT Months.Month,
COALESCE(data.ExpenseAmount, 0) AS ExpenseAmount,
COALESCE(data.PaymentAmount, 0) AS PaymentAmount
COALESCE将为您提供0而不是NULL,其中没有与左连接匹配的行。
但是,您的查询还有其他问题。如果在同一个月有费用和付款,您只会获得行 - 请检查http://sqlfiddle.com/#!2/3f52a8/1,如果从一个表中删除部分数据,您就会看到问题。
这是一个可行的解决方案,可以为您提供所有月份,从两个表中总结数据,即使只有一个表存在。这可以通过将费用和付款作为单独的查询来处理,然后将它们连接在一起。
SELECT Months.Month, COALESCE(expensedata.ExpenseAmount, 0) AS ExpenseAmount, COALESCE(paymentdata.PaymentAmount, 0) AS PaymentAmount
FROM
(SELECT DATE_FORMAT(now(), '%m/%y') AS Month
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 1 MONTH), '%m/%y')
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 2 MONTH), '%m/%y')
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 3 MONTH), '%m/%y')
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 4 MONTH), '%m/%y')
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 5 MONTH), '%m/%y')
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 6 MONTH), '%m/%y')
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 7 MONTH), '%m/%y')
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 8 MONTH), '%m/%y')
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 9 MONTH), '%m/%y')
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 10 MONTH), '%m/%y')
UNION SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 11 MONTH), '%m/%y')
) AS Months
LEFT JOIN
(SELECT SUM(price) AS ExpenseAmount, DATE_FORMAT(date_occurred,'%m/%y') AS Month
FROM expenses
WHERE user_id = 1
GROUP BY MONTH(date_occurred), YEAR(date_occurred)) expensedata ON Months.Month = expensedata.Month
LEFT JOIN
(SELECT SUM(amount) AS PaymentAmount, DATE_FORMAT(date_occurred,'%m/%y') AS Month
FROM payments
WHERE user_id = 1
GROUP BY MONTH(date_occurred), YEAR(date_occurred)) paymentdata ON Months.Month = paymentdata.Month
ORDER BY Months.Month;
显示此工作的SQL小提琴:http://sqlfiddle.com/#!2/3f52a8/5
答案 1 :(得分:0)
我认为你的问题是左连接。左边连接中的select语句的结果不包含任何0钱的结果...它看起来像你的
where payments.user_id = 1
是问题......
在以下链接中,您可以找到所有类型的联接的解释... http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/
希望有所帮助
答案 2 :(得分:0)
将ORDER BY data.Montha
替换为ORDER BY Months.MONTH
数据中没有“3/14”.Montha。