我有一个epos系统订单表。
我有几年的数据,我想知道每年每周的平均交易次数。即2014年与2013年等最繁忙的一天。
我可以通过这种方式获取信息:
SELECT ROUND(AVG(sales),1) AS dayaverage, oday, oyear FROM (
SELECT COUNT(oid) AS sales, DAYNAME(odate) AS oday , YEAR(odate) AS oyear
FROM orders
WHERE ostatus = 'completed'
GROUP BY DATE(odate)
ORDER BY YEAR(odate), DAYOFWEEK(odate)) t1
GROUP BY oday, oyear
ORDER BY oyear DESC, AVG(sales) DESC
这需要数据,但不是正确的格式。
我明白了:
"dayaverage" "oday" "oyear"
"28.9" "Saturday" "2015"
"17.1" "Sunday" "2015"
"15.0" "Tuesday" "2015"
"14.3" "Monday" "2015"
"13.1" "Wednesday" "2015"
"13.0" "Friday" "2015"
我创建了这个声明:
SELECT tsun.pyear, sunday,monday,tuesday, wednesday, thursday, friday, saturday FROM (
SELECT ROUND(AVG(payments),1) AS Sunday, pyear FROM (
SELECT COUNT(paymentid) AS payments, YEAR(DATETIME) AS pyear
FROM payments
WHERE DAYNAME(DATETIME) = "Sunday"
GROUP BY DATE(DATETIME)
ORDER BY YEAR(DATETIME), DAYOFWEEK(DATETIME)) t1
GROUP BY pyear
ORDER BY pyear DESC, AVG(payments) DESC) AS tsun
LEFT JOIN (SELECT * FROM (SELECT ROUND(AVG(payments),1) AS Monday, pyear FROM (
SELECT COUNT(paymentid) AS payments, YEAR(DATETIME) AS pyear
FROM payments
WHERE DAYNAME(DATETIME) = "Monday"
GROUP BY DATE(DATETIME)
ORDER BY YEAR(DATETIME), DAYOFWEEK(DATETIME)) t2
GROUP BY pyear
ORDER BY pyear DESC, AVG(payments) DESC) AS tmon) tmon2 ON tsun.pyear = tmon2.pyear
LEFT JOIN (SELECT * FROM (SELECT ROUND(AVG(payments),1) AS Tuesday, pyear FROM (
SELECT COUNT(paymentid) AS payments, YEAR(DATETIME) AS pyear
FROM payments
WHERE DAYNAME(DATETIME) = "Tuesday"
GROUP BY DATE(DATETIME)
ORDER BY YEAR(DATETIME), DAYOFWEEK(DATETIME)) t2
GROUP BY pyear
ORDER BY pyear DESC, AVG(payments) DESC) AS ttue) ttue2 ON tsun.pyear = ttue2.pyear
LEFT JOIN (SELECT * FROM (SELECT ROUND(AVG(payments),1) AS Wednesday, pyear FROM (
SELECT COUNT(paymentid) AS payments, YEAR(DATETIME) AS pyear
FROM payments
WHERE DAYNAME(DATETIME) = "Wednesday"
GROUP BY DATE(DATETIME)
ORDER BY YEAR(DATETIME), DAYOFWEEK(DATETIME)) t2
GROUP BY pyear
ORDER BY pyear DESC, AVG(payments) DESC) AS twed) twed2 ON tsun.pyear = twed2.pyear
LEFT JOIN (SELECT * FROM (SELECT ROUND(AVG(payments),1) AS Thursday, pyear FROM (
SELECT COUNT(paymentid) AS payments, YEAR(DATETIME) AS pyear
FROM payments
WHERE DAYNAME(DATETIME) = "Thursday"
GROUP BY DATE(DATETIME)
ORDER BY YEAR(DATETIME), DAYOFWEEK(DATETIME)) t2
GROUP BY pyear
ORDER BY pyear DESC, AVG(payments) DESC) AS tthu) tthu2 ON tsun.pyear = tthu2.pyear
LEFT JOIN (SELECT * FROM (SELECT ROUND(AVG(payments),1) AS Friday, pyear FROM (
SELECT COUNT(paymentid) AS payments, YEAR(DATETIME) AS pyear
FROM payments
WHERE DAYNAME(DATETIME) = "Friday"
GROUP BY DATE(DATETIME)
ORDER BY YEAR(DATETIME), DAYOFWEEK(DATETIME)) t2
GROUP BY pyear
ORDER BY pyear DESC, AVG(payments) DESC) AS tfri) tfri2 ON tsun.pyear = tfri2.pyear
LEFT JOIN (SELECT * FROM (SELECT ROUND(AVG(payments),1) AS Saturday, pyear FROM (
SELECT COUNT(paymentid) AS payments, YEAR(DATETIME) AS pyear
FROM payments
WHERE DAYNAME(DATETIME) = "Saturday"
GROUP BY DATE(DATETIME)
ORDER BY YEAR(DATETIME), DAYOFWEEK(DATETIME)) t2
GROUP BY pyear
ORDER BY pyear DESC, AVG(payments) DESC) AS tsat) tsat2 ON tsun.pyear = tsat2.pyear
这也以我想要的格式产生我想要的数据;
"pyear" "sunday" "monday" "tuesday" "wednesday" "thursday" "friday" "saturday"
"2015" "18.4" "13.0" "16.5" "14.3" "13.3" "17.3" "31.3"
"2014" "17.8" "19.0" "17.6" "15.3" "15.5" "20.2" "32.0"
"2013" "3.4" "3.9" "3.4" "3.7" "3.4" "4.5" "6.2"
"2012" "2.8" "4.8" "4.7" "4.8" "3.7" "5.7" "7.1"
"2011" "4.0" "7.1" "5.6" "6.2" "6.6" "5.4" "6.2"
"2010" "3.0" "5.5" "5.7" "5.2" "5.3" "4.6" "6.6"
"2009" "2.5" "4.3" "3.5" "4.9" "4.8" "2.9" "3.9"
但它不是很优雅!
我想知道的是,有更好的方法吗?
是否有类似第一个声明会产生类似第二个声明的东西?
我确信有一种聪明的方法可以做到这一点,就像使用案例陈述一样,但解决方案暂时让我失望了。有人有任何想法吗?
提前致谢,
马克
所以我得到了这个,谢谢戈登。
SELECT oyear,
ROUND(AVG(CASE WHEN oday = 'Monday' THEN sales END), 1) AS Mon,
ROUND(AVG(CASE WHEN oday = 'Tuesday' THEN sales END), 1) AS Tue,
ROUND(AVG(CASE WHEN oday = 'Wednesday' THEN sales END), 1) AS Wed,
ROUND(AVG(CASE WHEN oday = 'Thursday' THEN sales END), 1) AS Thu,
ROUND(AVG(CASE WHEN oday = 'Friday' THEN sales END), 1) AS Fri,
ROUND(AVG(CASE WHEN oday = 'Saturday' THEN sales END), 1) AS Sat,
ROUND(AVG(CASE WHEN oday = 'Sunday' THEN sales END), 1) AS Sun
FROM (SELECT COUNT(oid) AS sales, DAYNAME(odate) AS oday , YEAR(odate) AS oyear
FROM orders
WHERE ostatus = 'completed'
GROUP BY DATE(odate)
) d
GROUP BY oyear
ORDER BY oyear ASC
答案 0 :(得分:2)
使用条件聚合:
SELECT ROUND(AVG(sales),1) AS dayaverage, oday, oyear,
ROUND(AVG(CASE WHEN oday = 'Monday' THEN sales END), 1) as Mon,
ROUND(AVG(CASE WHEN oday = 'Tuesday' THEN sales END), 1) as Tue,
ROUND(AVG(CASE WHEN oday = 'Wednesday' THEN sales END), 1) as Wed,
ROUND(AVG(CASE WHEN oday = 'Thursday' THEN sales END), 1) as Thu,
ROUND(AVG(CASE WHEN oday = 'Friday' THEN sales END), 1) as Fri,
ROUND(AVG(CASE WHEN oday = 'Saturday' THEN sales END), 1) as Sat,
ROUND(AVG(CASE WHEN oday = 'Sun' THEN sales END), 1) as Sun
FROM (SELECT COUNT(oid) AS sales, DAYNAME(odate) AS oday , YEAR(odate) AS oyear
FROM orders
WHERE ostatus = 'completed'
GROUP BY DATE(odate)
) d
GROUP BY oyear
ORDER BY DESC;