简体   繁体   English

快速计算每种产品在过去6、3、1个月的平均月销售额

[英]Fast compute average monthly sales for the past 6, 3, 1 months per product

I'm using PHP/MySQL 我正在使用PHP / MySQL

I have about 2,000 products. 我有大约2,000种产品。 I have to compute the average monthly sales for the past 6, 3, 1 month(s) of each product and show it in the page at once... 我必须计算每个产品在过去6、3、1个月的平均每月销售额,并将其一次显示在页面中...

Currently I have the following code (loop for each product): 目前,我有以下代码(每个产品的循环):

$past_month_sales = $this->SalesPerProduct->getSalesForMonthYear( $acc_code,
                                                                $item_code, $past_month[0],
                                                                $past_month[1] );

$past_two_months_sales = $this->SalesPerProduct->getSalesForMonthYear( $acc_code,
                                                                    $item_code, $past_two_months[0],
                                                                    $past_two_months[1] );

$past_three_months_sales = $this->SalesPerProduct->getSalesForMonthYear( $acc_code,
                                                                    $item_code, $past_three_months[0],
                                                                    $past_three_months[1] );

$past_four_months_sales = $this->SalesPerProduct->getSalesForMonthYear( $acc_code,
                                                                    $item_code, $past_four_months[0],
                                                                    $past_four_months[1] );

$past_five_months_sales = $this->SalesPerProduct->getSalesForMonthYear( $acc_code,
                                                                    $item_code, $past_five_months[0],
                                                                    $past_five_months[1] );

$past_six_months_sales = $this->SalesPerProduct->getSalesForMonthYear( $acc_code,
                                                                    $item_code, $past_six_months[0],
                                                                    $past_six_months[1] );

//for past 3 months
if( $past_month_sales == 0
    || $past_two_months_sales == 0
    || $past_three_months_sales == 0){

    $past_three_sales_ave = "n/a";

}else{

    $past_three_sales_ave = round( ( $past_month_sales 
                        + $past_two_months_sales
                        + $past_three_months_sales )
                        / 3 );
}

//for past 6 months
if( $past_month_sales == 0
    || $past_two_months_sales == 0
    || $past_three_months_sales == 0
    || $past_four_months_sales == 0
    || $past_five_months_sales == 0
    || $past_six_months_sales == 0){

    $past_six_sales_ave = "n/a";

}else{
    $past_six_sales_ave = round( ( $past_month_sales
                        + $past_two_months_sales
                        + $past_three_months_sales
                        + $past_four_months_sales
                        + $past_five_months_sales
                        + $past_six_months_sales )
                        / 6 );
}

But the code above is very slow, even 100 products take ages to load... 但是上面的代码非常慢,即使100个产品也要花很长时间才能加载...

My getSalesForMonthYear function look like this: 我的getSalesForMonthYear函数如下所示:

function getSalesForMonthYear( $account_code, $item_code, $month, $year ){
    $sql = "select 
                SalesPerProduct.sales_value
            from 
                sales_per_products as SalesPerProduct
            where
                account_code = '{$account_code}' and
                item_code = '{$item_code}' and
                month = '{$month}' and
                year = '{$year}'";

    $val = $this->query($sql);

    if( empty( $val[0]['SalesPerProduct']['sales_value'] ) ){
        $val = 0;
    }else{
        $val = $val[0]['SalesPerProduct']['sales_value'];
    }
    return $val;
}

Any idea how this can be fast? 知道如何快速吗? TIA!!! TIA !!!

您不需要每次单击都更新数据,因此建立一个缓存表来保存数据并在每个时间段更新

You should look in to SQL commands like AVG 您应该查看像AVG这样的SQL命令

http://www.w3schools.com/sql/sql_func_avg.asp http://www.w3schools.com/sql/sql_func_avg.asp

Its always better to do the calculation on the database side. 在数据库端进行计算总是更好。 No code you write will go faster than doing it before extracting it. 您编写的任何代码都不会比提取代码之前执行的速度更快。

See that you have index your database good so it know what to do and when! 看到您的数据库索引很好,因此它知道该做什么和什么时候!

Thats the first you could do! 那就是您首先可以做的!

I think it will solve alot for you at this point. 我认为这将为您解决很多问题。

If you then want to take it even one step futher you could check in to this. 如果您想再进一步,可以检查一下。

http://www.sqlteam.com/article/intro-to-user-defined-functions-updated http://www.w3schools.com/sql/sql_view.asp http://www.sqlteam.com/article/intro-to-user-defined-functions-updated http://www.w3schools.com/sql/sql_view.asp

You could create a function and view that extract all avg calls in one sql query. 您可以创建一个函数并查看在一个sql查询中提取所有avg调用的函数。 No need for several connections. 无需多个连接。 Every connection will have some overhead starting up and so on that you could by pass again by doing everything on the database side! 每个连接的启动都会有一些开销,依此类推,您可以通过在数据库端进行所有操作来再次传递开销!

maybe use an general function and don't check for each month. 也许使用一般功能,而不是每个月检查一次。 and try to use indexes for months and sales_value 并尝试使用月份和sales_value的索引

/*
   $account_code - account
   $item_code - item
   $start_month - starting month - NOTE: this is integer: 1,2,....,10,11,12
   $months - number of months to query
   $year - the year
   and SUM to auto calculate the sales_value
*/
function getSalesForMonths( $account_code, $item_code, $start_month, $months, $year ){
    $addQuery = '';
    $finalQuery = '';

    for($i = 1; $i<=$months; $i++){
         $addQuery .= 'month='.($start_month+$i);
         if($i<$months){ $addQuery .= ' OR '; }
    }

    if($months > 1){
        $finalQuery = '('.$addQuery.')';
    } else {
        $finalQuery = $addQuery;
    }

    $sql = "select 
            SUM(SalesPerProduct.sales_value)
        from 
            sales_per_products as SalesPerProduct
        where
            account_code = '{$account_code}' and
            item_code = '{$item_code}' and
            ".$finalQuery." and
            year = '{$year}'";

    $val = $this->query($sql);

    if( empty( $val[0]['SalesPerProduct']['sales_value'] ) ){
        $val = 0;
    }else{
        $val = $val[0]['SalesPerProduct']['sales_value'];
    }
    return $val;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM