Какой самый быстрый способ выполнить этот запрос MySQL, отсортированный по возрастанию и уменьшению количества? - PullRequest
2 голосов
/ 24 апреля 2011

У меня есть таблица, в которой записываются все продажи 350+ товаров в магазине; столбец включает название продукта и дату.

Я работаю над страницей, на которой перечислены самые быстро движущиеся товары, основанные на проценте увеличения продаж, но мой запрос очень медленный, учитывая, что существует более 350 товаров и более 60000 записей.

  SELECT product_name, date 
    FROM data 
ORDER BY ((SELECT COUNT(ID) 
             FROM data 
            WHERE date='$date2') - 
          (SELECT COUNT(ID) 
             FROM data 
            WHERE date='$date1')) / 
          (SELECT COUNT(ID) 
             FROM data 
            WHERE date='$date1') DESC

Мои знания MySQL весьма ограничены, поэтому любая помощь сообщества будет оценена.

Образец данных:

| id | product_name    | date       |
| 1  | pen             | 2011-04-22 |
| 2  | pencil          | 2011-04-22 |
| 3  | pen             | 2011-04-23 |
| 4  | pen             | 2011-04-23 |
| 5  | pencil          | 2011-04-23 |
| 6  | pen             | 2011-04-23 |
| 7  | pencil          | 2011-04-23 |

Ожидаемый результат:

1  Pen     200%  (3-1)/1
2  Pencil  100%  (2-1)/1

Ответы [ 2 ]

1 голос
/ 25 апреля 2011

Устранить двойной выбор
Если вы создаете сохраненную функцию, например так:

DELIMITER $$

CREATE FUNCTION SalesIncrease(OldSales integer, NewSales integer)
  RETURNS float
BEGIN
  DECLARE Result float;
  IF OldSales = 0 THEN SET result = 1; /*100%*/
  ELSE BEGIN
    IF NewSales = 0 THEN SET result = -1; /*-100%*/ 
    ELSE SET Result = (NewSales - OldSales) / OldSales;
    END IF;
  END; END IF;

  RETURN result;
END $$

DELIMITER ;

Теперь измените запрос на

//don't forget to escape $date1 and $date2 to protect against SQL-injection
$date1 = mysql_real_escape_string($date1);
$date2 = mysql_real_escape_string($date2);

$sql_query = "SELECT oldsales.product_name, oldsales.date, 
  SalesIncrease( COUNT(oldsales.ID), COUNT(newsales.ID)) as Increase 
FROM data AS oldsales
LEFT join data AS newsales ON (oldsales.id = newsales.id)
WHERE oldsales.date = '$date1' AND newsales.date = '$date2'
ORDER BY Increase ";
0 голосов
/ 25 апреля 2011
SELECT COALESCE(d2.product_name, d1.product_name) AS product_name, 
       COALESCE(100*(COALESCE(d2.n, 0)/d1.n -1), 'Infinity') AS pct_increase
FROM (SELECT product_name, COUNT(id) AS n FROM data WHERE date=$date1
     GROUP BY product_name) as d1 
FULL OUTER JOIN 
     (SELECT product_name, COUNT(id) AS n FROM data WHERE date=$date2
     GROUP BY product_name) as d2
ON d1.product_name=d2.product_name
ORDER BY 2 DESC; 
/* BY 2 == second column, nonstandard SQL but works. Can also copy column expression */

Убедитесь, что у вас есть индекс на имя_продукта и индекс на дату.

COALESCE предназначен для решения крайних случаев отсутствия продаж на одном издаты, а также использование OUTER JOIN.

...