我需要真正的专业DBA帮助!我找不到使用LEFT JOIN,UNION,UNION ALL或者IFNULL(salesblah,0)在销售数据表日期表上的合理解决方案。由于销售代表可能存在差距,因此单独对销售数据运行查询。当然,我可以在PHP中创建一个数组来按日期汇总数据,但是必须要有一个我看不到的优雅解决方案,而这个个人挑战让我疲惫不堪。必须有一个简短而甜蜜的解决方案。
在服务器上使用MySQL 5.5.15,销售数据的摘录(目前为800,000行,每天增长)如下所示:
Rep Date QtyOrdered PriceEach
--------------------------------------------------
1 2011-06-05 4 1457.23
1 2011-08-01 1 3342.54
1 2011-08-11 12 112.23
2 2011-05-02 3 2654.23
2 2011-08-23 22 423.43
. ... ... ...
另一张表只是2000-01-01至2034-12-31之间的一列日期
使用(或不使用)日期表,当我在查询中调用rep 1时,如何获得此结果:
YYYY-MM Total Sales
------------------------
2010-08 0
2010-09 0
2010-10 0
2010-11 0
2010-12 0
2011-01 0
2011-02 0
2011-03 0
2011-04 0
2011-05 0
2011-06 5828.92
2011-07 0
2011-08 4960.14
我真的希望收掉那些不礼貌的言辞。谢谢你的才华。
编辑:Derek的左连接解决方案省略了非零月份。 Nerf的子查询方法总计为一个月。我相信正是GROUP BY正在杀死非零月份。
谢谢!我相信最简单的方法是让PHP通过数组运行结果。最终,这是通过GD构建一个月的图表,混合解决方案可以在该部分中省去一步。
再次感谢你!
答案 0 :(得分:1)
这应该让你非常接近。没有经过测试,但逻辑应该是正确的。
select
cast(year(dt.date) as varchar(4)) + '-' + cast(month(dt.date) as varchar(2)),
sum(QtyOrdered * PriceEach)
from salesdata sd
right join datetbl dt
on sd.date = dt.date
where sd.rep = 1 and dt.date between '8/1/2010' and '8/31/2011'
group by cast(year(dt.date) as varchar(4)) + '-' + cast(month(dt.date) as varchar(2))
答案 1 :(得分:1)
SELECT CONCAT_WS("-", YEAR(date), DATE_FORMAT(date, '%m') ) AS "YYYY-MM", SUM(Total_Sales) AS "Total Sales"
FROM(
SELECT dt.date, SUM(QtyOrdered * PriceEach) AS Total_Sales
FROM sales_data sd
LEFT JOIN datetbl dt
ON sd.Date = dt.date
WHERE sd.rep = 1 AND dt.date BETWEEN '2011-08-01' AND '2011-08-31'
GROUP BY dt.date
) AS derived_table
答案 2 :(得分:1)
我遇到了同样的问题,我得到的解决方案没有使用JOIN或任何复杂的东西。要避免的是按总计分组。这将显示按年,月和日排序的所有销售,包括根本没有销售的日期(dayTotal将等于0)
SELECT Year(transactions.paymentdate) AS orderYear,Month(transactions.paymentdate) AS orderMonth, Day(transactions.paymentdate) AS orderDay,
SUM(transactions.amount) AS dayTotal
FROM transactions
group by orderYear desc,orderMonth desc, orderDay desc