如何计算每个学期的营业额

时间:2017-08-02 15:17:14

标签: mysql sql

我在column中有一个SQL table。这包含date的交货单。

所以相同的日期可以重复(在一天内我们提交了几个订单),如下所示:

05-01-16
05-01-16
05-01-16
08-01-16
08-01-16
14-01-16
22-01-16
22-01-16
04-02-16
05-02-16
05-02-16

我想,在each 6 months中计算每篇文章营业额的AVG,我解释一下:

From January to June ==> Turnover 1
From Febrary to July ==> Turnover 2
From March to August ==> Turnover 3
From April to September ==> Turnover 4
From May to Obtober ==> Turnover 5
From June to November ==> Turnover 6
From July to December ==> Turnover 7

我已经按照下面的请求提取了月份,但我无法动态计算(因为我的数据应该每月更改一次)营业额如上例所示:

select distinct extract (month from Article) as mt 
order by mt

我尝试使用cursor,但我无法找到最佳解决方案。

我在the first 6 months(我手动完成)的每篇文章中为每个客户计算了营业额的请求如下:

select "LRU", "Client", round(sum("Montant_fac_eur"))
from "foundry"
where "Nature"='Repair' 
and "Client"={{w_widget3.selectedValue}}
and "annee"='2016'
and extract (month from "date") between '1' and '6'


group by "LRU", "Client"

她的结果如下:

 LRU            Client  round
"article1"       4001   8859     Turnover of article1 from January to June
"article2"       4001   94315    Turnover of article2 from January to June
"article3"       4001   273487   Turnover of article3 from January to June
"article4"       4001   22292    Turnover of article4 from January to June
"article5"       4001   22292    Turnover of article5 from January to June
"article6"       4001   42590    Turnover of article6 from January to June
"article7"       4001   9965     Turnover of article7 from January to June
"article8"       4001   39654    Turnover of article8 from January to June
"article9"       4001   3883     Turnover of article9 from January to June
"article10"      4001   41612    Turnover of article10 from January to June

我想做一个循环来计算每6个月的营业额而不用手动写它是否可能? 有人可以帮助我,给我一个解决方案或建议我该怎么办? 谢谢。

3 个答案:

答案 0 :(得分:6)

在这里,您可以查看问题的简化定义和解决方案(如果我理解正确的话): http://sqlfiddle.com/#!9/48a2e1/1

CREATE TABLE foundry
(
    lru varchar(50) NOT NULL,
    client int  NOT NULL,
    purchase_date date,
    price int NOT NULL
);

INSERT INTO foundry (lru, client, purchase_date, price) VALUES
("article1", 4001, "01-01-16", 100),
("article1", 4001, "01-01-17", 200),
("article1", 4001, "01-02-16", 300),
("article1", 4001, "01-04-16", 400),
("article1", 4001, "01-06-16", 500),
("article1", 4001, "01-08-16", 600),
("article1", 4001, "01-10-16", 700),
("article1", 4001, "01-11-16", 800),
("article1", 4002, "01-01-16", 900),
("article1", 4002, "01-07-16", 1000),
("article1", 4002, "01-12-16", 1100);

基本上我们有一个包含四列的表:lru(文章名称),客户,购买日期和一些价格。

解决方案如下:

SELECT lru, client, avg(price), COUNT(*) as total_items,
MONTHNAME(STR_TO_DATE(L, '%m')) as start_month, MONTHNAME(STR_TO_DATE(R, '%m')) as end_month FROM foundry,
(
  SELECT 1 as L, 6 as R
    UNION ALL
  SELECT 2, 7
    UNION ALL
  SELECT 3, 8
    UNION ALL
  SELECT 4, 9
    UNION ALL
  SELECT 5, 10
    UNION ALL
  SELECT 6, 11
    UNION ALL
  SELECT 7, 12
) months
WHERE month(purchase_date) >= L AND month(purchase_date) <= R
GROUP BY lru, client, L, R

这个想法是:

  1. 生成所有可能的月份组合:1-6,2-7,...,7,12
  2. 使用生成的月份组合加入源数据
  3. 将AVG与GROUP BY一起使用
  4. 结果:

    lru     client  avg(price)  total_items     start_month     end_month
    article1    4001    300     5   January     June
    article1    4001    400     3   February    July
    article1    4001    500     3   March   August
    article1    4001    500     3   April   September
    article1    4001    600     3   May     October
    article1    4001    650     4   June    November
    article1    4001    700     3   July    December
    article1    4002    900     1   January     June
    article1    4002    1000    1   February    July
    article1    4002    1000    1   March   August
    article1    4002    1000    1   April   September
    article1    4002    1000    1   May     October
    article1    4002    1000    1   June    November
    article1    4002    1050    2   July    December
    

答案 1 :(得分:2)

我会为每个六个月的报道推荐常用的表格表达式。 https://technet.microsoft.com/en-us/library/ms186243(v=sql.105).aspx 喜欢: 用tp1 (Turnoverperiod,Averagevaule) 如 ( 选择 'Period1'作为Turnoverperiod, AVG(营业额)作为平均值 其中date1.startdate和period2.enddate之间的日期 ) , tp2为 ( .... tp2 )

从tp1中选择* 联盟 从tp2中选择*

另外,您可以创建动态sql字符串(nvarchar(max)),您可以以编程方式附加联合查询,然后使用sp_executesql语句。

答案 2 :(得分:2)

我不确定您使用的是哪种RDBM,因此这里有一个可能的ANSI SQL解决方案(使用您的RDBM模拟)

尝试分两步解决此问题:

  1. 在源表中使用基本的group by语法在表单中创建一个视图(假设你称之为v_turnover_per_month):

    article  month    turnover
    art1     201701  1000
    art1     201702  1020
    ...      ...      ...
    art2     201701  5000
    ...      ...      ...
    
  2. 使用以下select语句

    SELECT  article,
            'Turnover from ' || m1.month || ' until ' || m6.month as title,
            max(m1.turnover + m2.turnover + m3.turnover + m4.turnover + m5.turnover + m6.turnover) as total_turnover_6month
    
    FROM v_turnover_per_month as m6
    JOIN v_turnover_per_month as m5 ON m6.article = m5.article and m5.month+1=m6.month
    JOIN v_turnover_per_month as m4 ON m6.article = m4.article and m4.month+1=m5.month
    JOIN v_turnover_per_month as m3 ON m6.article = m3.article and m3.month+1=m4.month
    JOIN v_turnover_per_month as m2 ON m6.article = m2.article and m2.month+1=m3.month
    JOIN v_turnover_per_month as m1 ON m6.article = m1.article and m1.month+1=m2.month
    
    GROUP BY 1, 2;