涉及week(),year(),curdate()和weekday()的MySQL案例

时间:2015-05-19 18:49:33

标签: mysql

我有一个数据集,其中包含订单日期及其变体(周(),年(),工作日()等)。当且仅当订单日期符合特定条件时(例如,周= 51,年= 2015),我想创建对订单单位求和的逻辑。

输出I' m寻找:

PRODUCT_ID, product_sku, monday_units_sold, tuesday_units_sold, wednesday_units_sold, thursday_units_sold, friday_units_sold, saturday_units_sold, sunday_units_sold

这里需要注意的是,如果订单日期发生在上周,我只想要在当天销售的单位。另外,我不希望此计算依赖于where子句中的任何条件。我已经缩短了保持简单的要求,但实际上我会在一个select子句中查看不同的时间框架(生命到期,mtd,ytd等)。

这是我到目前为止无法使用的代码。

 select
    product_id,
    sku_code,
    case when week = current_week and year = current_year and weekday = 0 then sum(units_sold) end as monday_units,
    case when week = current_week and year = current_year and weekday = 1 then sum(units_sold) end as tuesday_units,
    case when week = current_week and year = current_year and weekday = 2 then sum(units_sold) end as wednesday_units,
    case when week = current_week and year = current_year and weekday = 3 then sum(units_sold) end as thursday_units,
    case when week = current_week and year = current_year and weekday = 4 then sum(units_sold) end as friday_units,
    case when week = current_week and year = current_year and weekday = 5 then sum(units_sold) end as saturday_units,
    case when week = current_week and year = current_year and weekday = 6 then sum(units_sold) end as sunday_units

from
    -- This table is at the order level whereas the final result rolls up into the product/sku level.
    (select
        order_date,
        order_id,
        product_id,
        sku_code,
        weekday(order_date) as weekday,
        week(order_date) as week,
        month(order_date) as month,
        year(order_date) as year,
        yearmonth(order_date) as yearmonth,
        units_sold,
        product_sales,
        -- I tried calculating this in each case when in the select statement above, 
        -- but moved it down here in an attempt to problem solve why my calculations aren't working.
        week((curdate() - interval 1 day)) as current_week, 
        year((curdate() - interval 1 day)) as current_year,
    from product_sales
    ) a

1 个答案:

答案 0 :(得分:1)

我认为您可以简化查询:

select product_id, sku_code
     , year(order_date) as order_year
     , weekofyear(order_date) as order_week
     , sum(case weekday(order_date) when 0 then units_sold else 0 end) as monday_units
     , sum(case weekday(order_date) when 1 then units_sold else 0 end) as tuesday_units
     , sum(case weekday(order_date) when 2 then units_sold else 0 end) as wednesday_units
     , sum(case weekday(order_date) when 3 then units_sold else 0 end) as thursday_units
     , sum(case weekday(order_date) when 4 then units_sold else 0 end) as friday_units
     , sum(case weekday(order_date) when 5 then units_sold else 0 end) as saturday_units
     , sum(case weekday(order_date) when 6 then units_sold else 0 end) as sunday_units
from
    (
        select
            order_date,
            order_id,
            product_id,
            sku_code,
            units_sold,
            product_sales
        from product_sales
    ) as a
 -- Example of WHERE condition:
where year(order_date) = 2015 and weekofyear(order_date) = 51
group by product_id, sku_code, order_year, order_week;

由于表可能非常大,可能最好的方法是创建临时表,索引它,然后从该临时表中选择。像这样:

-- If the temp table exists, drop it
drop table if exists temp_product_sales;
-- Create a temporary table with the data you're interested.
-- I suggest you add the WHERE conditions in this SELECT, because it may
-- speed up the final SELECT.
-- Notice that I'm not grouping the data just yet... that will be done 
-- with the final SELECT
create temporary table temp_product_sales
        select
            order_date,
            order_id,
            product_id,
            sku_code,
            units_sold,
            product_sales,
            year(order_date) as order_year,
            weekofyear(order_date) as order_week,
            weekday(order_date) as order_weekday
        from product_sales
        -- Optional: Add WHERE conditions here
        ;
-- IMPORTANT: Add the relevant indexes to your temp table. This will
-- speed up things
alter table temp_product_sales
    add index odt(order_date),
    add index oid(order_id),
    add index pid(product_id),
    add index sku(sku_code),
    add index oy(order_year),
    add index ow(order_week),
    add index owd(order_weekday);
-- Finally, execute your final query:
select product_id, sku_code, order_year, order_week
     , sum(case order_weekday when 0 then units_sold else 0 end) as monday_units
     , sum(case order_weekday when 1 then units_sold else 0 end) as tuesday_units
     , sum(case order_weekday when 2 then units_sold else 0 end) as wednesday_units
     , sum(case order_weekday when 3 then units_sold else 0 end) as thursday_units
     , sum(case order_weekday when 4 then units_sold else 0 end) as friday_units
     , sum(case order_weekday when 5 then units_sold else 0 end) as saturday_units
     , sum(case order_weekday when 6 then units_sold else 0 end) as sunday_units
from temp_product_sales
-- Example of WHERE condition:
where order_year = 2015 and order_week = 51
group by product_id, sku_code, order_year, order_week;

请记住:临时表仅对创建它们的连接可见,并在连接关闭或终止后被删除。

希望这有帮助