如何获得过去一年的有效订单

时间:2018-01-24 05:26:25

标签: mysql mariadb

我有一张包含开始和结束日期的表格。根据该表,我必须获得过去12个月的有效订单。

在结束日期,NULL表示它是现在的有效订单。

表基本理念

enter image description here

预期产出

enter image description here

根据过去的经验,我能够在今年的1月份编写这样的查询,但我需要它在所有月份,如上图所示

select
      mnth.num, count(*)
from (
    select 1 AS num union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all 
    select 7 union all select 8 union all select 9 union all select 10 union all select 11 union all select 12
    ) mnth
left join (    
      select
            o.id
          , case 
               when o.start_date < date_format(current_date(), '%Y-01-01') then 1
               else month(o.start_date)
               end AS start_month
          , case 
               when o.end_date < date_format(current_date(), '%Y-01-01') then 0
               when o.end_date >= date_format(current_date(), '%Y-01-01') then month(o.end_date)
               else month(current_date())
               end AS end_month
      from order o
      ) active_work_orders on mnth.num between active_work_orders.start_month and active_work_orders.end_month  
where mnth.num <= month(current_date())
group by
      mnth.num
;

根据输出,我必须生成一个图表。请帮忙解决这个问题

小提琴链接click here

2 个答案:

答案 0 :(得分:1)

您可以借助extract function提取年份和月份,然后根据该group by进行操作。

然后,为了显示,您可以使用date_format function

所以,在这里:

SELECT 
    DATE_FORMAT(start_date, '%b-%y') AS `Month`, COUNT(*) AS `Active`
FROM
    orders
WHERE
    end_date IS NULL
GROUP BY EXTRACT(YEAR_MONTH FROM start_date)

仅从过去12个月获得结果,您可以使用以下内容:

SELECT 
    `month_list`.`month`, IFNULL(`active_orders`.`active_count`, 0) AS `active_count`
FROM 
    (SELECT 
        *
    FROM
        (SELECT DATE_FORMAT(NOW(), '%b-%y') AS `month` 
            UNION 
        SELECT DATE_FORMAT(NOW() - INTERVAL 1 MONTH, '%b-%y') 
            UNION 
        SELECT DATE_FORMAT(NOW() - INTERVAL 2 MONTH, '%b-%y') 
            UNION 
        SELECT DATE_FORMAT(NOW() - INTERVAL 3 MONTH, '%b-%y') 
            UNION 
        SELECT DATE_FORMAT(NOW() - INTERVAL 4 MONTH, '%b-%y') 
            UNION 
        SELECT DATE_FORMAT(NOW() - INTERVAL 5 MONTH, '%b-%y') 
            UNION 
        SELECT DATE_FORMAT(NOW() - INTERVAL 6 MONTH, '%b-%y') 
            UNION 
        SELECT DATE_FORMAT(NOW() - INTERVAL 7 MONTH, '%b-%y') 
            UNION 
        SELECT DATE_FORMAT(NOW() - INTERVAL 8 MONTH, '%b-%y') 
            UNION 
        SELECT DATE_FORMAT(NOW() - INTERVAL 9 MONTH, '%b-%y') 
            UNION 
        SELECT DATE_FORMAT(NOW() - INTERVAL 10 MONTH, '%b-%y') 
            UNION 
        SELECT DATE_FORMAT(NOW() - INTERVAL 11 MONTH, '%b-%y')) 
    AS `months`) as `month_list`
LEFT JOIN
    (SELECT 
        DATE_FORMAT(start_date, '%b-%y') AS `month`, COUNT(*) AS `active_count`
    FROM
        `order`
    WHERE
        end_date IS NULL
    GROUP BY EXTRACT(YEAR_MONTH FROM start_date)) as `active_orders` on `month_list`.`month` = `active_orders`.`month`;

答案 1 :(得分:1)

也许是这样的

select mthnum,
        count(*) 
from
(
select mthnum, o.*,year(start_date)* 12 + month(start_date),year(end_date) * 12 + month(end_date)
from
(
    #select 2016*12 + 11 AS mthnum union all select 2016*12 + 12 union all select 2017*12 + 1 union all select 2017*12 + 2
    select 2017*100 + 2 as mthnum
     union all select 2017*100 + 3 union all select 2017*100 + 4 union all select 2017*100 + 5 union all select 2017*100 + 6
     union all select 2017*100 + 7 union all select 2017*100 + 8 union all select 2017*100 + 9 union all select 2017*100 + 10
     union all select 2017*100 + 11 union all select 2017*100 + 12 union all select 2018*100 + 1
) mth
cross join
(select * from order_test_new #where order_num = 1288
) o
) s where (s.mthnum >= year(s.start_date)*100  + month(start_date))  and 
    (end_date is null or s.mthnum <= year(end_date) * 100 + month(s.end_date))
group by mthnum

结果

+--------+----------+
| mthnum | count(*) |
+--------+----------+
| 201702 |        9 |
| 201703 |        9 |
| 201704 |        9 |
| 201705 |        8 |
| 201706 |        8 |
| 201707 |        8 |
| 201708 |        8 |
| 201709 |        7 |
| 201710 |        7 |
| 201711 |        6 |
| 201712 |        6 |
| 201801 |        6 |
+--------+----------+
12 rows in set (0.00 sec)

这认为带有和end_date的订单在end_date月份中处于活动状态。