2016-08-21 41 views
1

我有一个看起来像这样的SQL小提琴数据库:http://sqlfiddle.com/#!9/aa02e/1SQL:分组平均如果/箱SELECT语句

CREATE TABLE Table1 
    (`Store` varchar(1), `Date` date, `Product` varchar(2), `Weekday` int, `Month` int, `Revenue` float) 
; 

INSERT INTO Table1 
    (`Store`, `Date`, `Product`, `Weekday`, `Month`, `Revenue`) 
VALUES 
    ('a', '20160101', 'aa', 5, 1, 1.5), 
    ('a', '20160101', 'bb', 5, 1, 4), 
    ('a', '20160101', 'cc', 5, 1, 3.5), 
    ('a', '20160108', 'dd', 5, 1, 2.5), 
    ('a', '20160108', 'ee', 5, 1, 5), 
    ('b', '20160204', 'aa', 4, 2, 9.5), 
    ('b', '20160204', 'bb', 4, 2, 4), 
    ('b', '20160204', 'cc', 4, 2, 3), 
    ('b', '20160211', 'dd', 4, 2, 1.5), 
    ('b', '20160211', 'ee', 4, 2, 2.5) 
; 

SELECT * FROM table1; 
+-------+------------+---------+---------+-------+---------+ 
| Store | Date  | Product | Weekday | Month | Revenue | 
+-------+------------+---------+---------+-------+---------+ 
| a  | 2016-01-01 | aa  |  5 |  1 |  1.5 | 
| a  | 2016-01-01 | bb  |  5 |  1 |  4 | 
| a  | 2016-01-01 | cc  |  5 |  1 |  3.5 | 
| a  | 2016-01-08 | dd  |  5 |  1 |  2.5 | 
| a  | 2016-01-08 | ee  |  5 |  1 |  5 | 
| b  | 2016-02-04 | aa  |  4 |  2 |  9.5 | 
| b  | 2016-02-04 | bb  |  4 |  2 |  4 | 
| b  | 2016-02-04 | cc  |  4 |  2 |  3 | 
| b  | 2016-02-11 | dd  |  4 |  2 |  1.5 | 
| b  | 2016-02-11 | ee  |  4 |  2 |  2.5 | 
+-------+------------+---------+---------+-------+---------+ 

它显示了存储含收入数据。产品,日期和相应的日/月。 我想选择以下内容:

  • 商店
  • 每月收入总计(即什么是商店一月的总收入是多少?)
  • 平日收入平均值(即什么是平均收入商店一个星期四?)

第一个和第二个项目符号很简单,但我有最后一个问题。 目前,它需要所有产品和所有日期的平均值(假设星期几匹配)。我需要的是以下步骤:

  • 总结一家商店和某个特定日期的所有收入11)如果该日期具有相同的工作日(这里星期四)
  • 取两个值的平均值(例如平均(16.5,4)= 10.25)

我怎样才能做到呢? 谢谢

下面是该查询:

SELECT 
    Store, 
    SUM(CASE WHEN Month = 1 THEN Revenue ELSE NULL END) AS REVENUE_JAN, 
    SUM(CASE WHEN Month = 2 THEN Revenue ELSE NULL END) AS REVENUE_FEB, 
    AVG(CASE WHEN Weekday = 4 THEN Revenue ELSE NULL END) AS REVENUE_THU, 
    AVG(CASE WHEN Weekday = 5 THEN Revenue ELSE NULL END) AS REVENUE_FRI 
FROM Table1 
GROUP BY 
    Store 
; 
+0

请直接将所有相关信息添加到您的问题。链接中断,尤其是SQLFiddle –

+0

我不明白月份和工作日专栏的功能。此外,我怀疑你的意思是DECIMAL而不是FLOAT – Strawberry

+0

月是本月的整数(即1 = 1月),周日是当天的整数(即1 =星期一) – Berbatov

回答

1

的平日平均是棘手的。您的查询得到每个工作日的平均“订单大小”。但是你想要总收入。

一种方法是首先按工作日汇总,但这有点混乱。取而代之的是,你可以通过天数除以总收入使用计算平均的这一招:

SELECT Store, 
     SUM(CASE WHEN Month = 1 THEN Revenue ELSE NULL END) AS REVENUE_JAN, 
     SUM(CASE WHEN Month = 2 THEN Revenue ELSE NULL END) AS REVENUE_FEB, 
     (SUM(CASE WHEN Weekday = 4 THEN Revenue END)/
     COUNT(DISTINCT CASE WHEN Weekday = 4 THEN Date END) 
     ) AS REVENUE_THU, 
     (SUM(CASE WHEN Weekday = 5 THEN Revenue END)/
     COUNT(DISTINCT CASE WHEN Weekday = 5 THEN Date END) 
     ) AS REVENUE_FRI 
FROM Table1 
GROUP BY Store; 
1
SELECT 
    t1.store, 
    SUM(CASE WHEN Month = 1 THEN Revenue ELSE NULL END) AS REVENUE_JAN, 
    SUM(CASE WHEN Month = 2 THEN Revenue ELSE NULL END) AS REVENUE_FEB, 
    daily.REVENUE_THU, 
    daily.REVENUE_FRI 
FROM Table1 t1 
JOIN (
    SELECT 
    Store, 
    weekday, 
    avg(CASE WHEN weekday = 4 THEN sum_rev END) as REVENUE_THU, 
    avg(CASE WHEN weekday = 5 THEN sum_rev END) as REVENUE_FRI 
    FROM (
    SELECT 
     Store, date, weekday, 
     SUM(revenue) AS sum_rev 
    FROM Table1 
    GROUP BY 
     Store, date, weekday 
) AS foo 
    GROUP BY Store, weekday 
) AS daily ON daily.store = t1.store 
GROUP BY 
    t1.store 
0

这个怎么样解决它选择店面的选择当天返回平均

CREATE PROCEDURE sumForDayStore(IN vday INTEGER, IN vStore VARCHAR(50)) 
BEGIN 
    DECLARE totalDays INTEGER; 
    DECLARE totalRevenu INTEGER; 

    SET totalDays = (SELECT count(*) FROM Table1 WHERE WeekDay = vDay AND store = vStore); 
    SET totalRevenu = (SELECT sum(Revenue) FROM Table1 WHERE WeekDay = vDay AND store = vStore); 

    SELECT totalRevenu/totalDays; 
END; 

CALL sumForDayStore(5,'a');

0

这个怎么样:

SELECT mnth.Store, REVENUE_JAN, REVENUE_FEB, avg(rthu) REVENUE_THU, avg(rfri) REVENUE_FRI 
FROM 
(Select Store, sum(case when Month = 1 then Revenue else NULL END) REVENUE_JAN, 
sum(case when Month = 2 then Revenue else NULL END) REVENUE_FEB 
From Table1 group by Store) as mnth 

join 

(Select Store, sum(case when Weekday = 4 then Revenue end) rThu, 
sum(case when Weekday = 5 then Revenue end) rFri from Table1 group by Store, Date) as dys 

on mnth.Store = dys.Store 

group by mnth.Store, REVENUE_JAN, REVENUE_FEB 

我比较这与第一个答案的查询性能,它是根据SQL服务器执行计划更好的性能(更快的1.6倍)。也许这对更大的数据集有帮助。