Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Средняя цена товара / 11 сообщений из 11, страница 1 из 1
20.09.2013, 15:17:03
    #38402865
SharuPoNemnogu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Средняя цена товара
есть таблица, ну скажем такая:
id name price
1 продукт1 17800
2 продукт 2 23400
3 продукт 3 38900
..
n продукт n цена n

нужно найти среднее значение price. НО! Не просто высчитать среднее, а некий СУЩЕСТВУЮЩИЙ price? который более менее посредине между min и max.
Я так понимаю, что нужно высчитать среднее, а потом найти ближайшее к нему, но не догоню как сделать.

Помогите с запросом.
...
Рейтинг: 0 / 0
20.09.2013, 15:37:28
    #38402892
Cygapb-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Средняя цена товара
Код: sql
1.
2.
3.
4.
select *
from test
order by ABS(price-(select AVG(price) from test))
limit 1
...
Рейтинг: 0 / 0
20.09.2013, 17:04:15
    #38403044
javajdbc
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Средняя цена товара
Cygapb-007
Код: sql
1.
2.
3.
4.
select *
from test
order by ABS(price-(select AVG(price) from test))
limit 1



наверно будет быстрее найти среднее, затем
ближайший сверху (по индексу) и ближайший снизу (по индексу) и выбрать
самый "ближайший" из двух.

Ордер по функции --- точно полный скан
...
Рейтинг: 0 / 0
20.09.2013, 17:53:55
    #38403095
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Средняя цена товара
SharuPoNemnoguнужно найти среднее значение price. НО! Не просто высчитать среднее, а некий СУЩЕСТВУЮЩИЙ price? который более менее посредине между min и max.Может, вам нужна медиана ?
...
Рейтинг: 0 / 0
20.09.2013, 18:06:52
    #38403107
Cygapb-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Средняя цена товара
javajdbcнаверно будет быстрее найти среднее, затем
ближайший сверху (по индексу) и ближайший снизу (по индексу) и выбрать
самый "ближайший" из двух.

Ордер по функции --- точно полный сканНе уверен, что это быстрее :)
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
select * 
from (select @avg:=AVG(price)avg from Test)a
cross join (
   select * 
   from (
      (select *, ABS(price-@avg)delta from Test where price>=@avg order by price limit 1)
      union all
      (select *, ABS(price-@avg)delta from Test where price<=@avg order by price desc limit 1)
      ) u
   order by u.delta limit 1
   ) c
...
Рейтинг: 0 / 0
20.09.2013, 18:25:57
    #38403132
Cygapb-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Средняя цена товара
...
Рейтинг: 0 / 0
20.09.2013, 18:28:20
    #38403136
Aleksandr Kuzminsky
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Средняя цена товара
Если считать среднее, то без скана не обойтись.
Но, если подойдет (min(price) + max(price) ) /2 вместо среднего, то можно так.
Код: sql
1.
2.
3.
4.
5.
6.
CREATE TABLE `products` (
  `id` int(11) NOT NULL,
  `price` float DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `price` (`price`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1



Код: sql
1.
2.
3.
select id, price from products a 
join (select min(price) mi , max(price) ma from products )  b 
WHERE a.price >= (b.mi +b.ma)/2 limit 1;



Код: plaintext
1.
2.
3.
4.
5.
6.
mysql> select count(*) from products;
+----------+
| count(*) |
+----------+
|    10000 |
+----------+
1 row in set (0.00 sec)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
mysql> select id, price from products a join (select min(price) mi , max(price) ma from products )  b WHERE a.price >= (b.mi +b.ma)/2 limit 1;
+------+----------+
| id   | price    |
+------+----------+
| 4123 | 0.500079 |
+------+----------+
1 row in set (0.00 sec)


mysql> show status like 'Hand%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Handler_commit             | 1     |
| Handler_delete             | 0     |
| Handler_discover           | 0     |
| Handler_prepare            | 0     |
| Handler_read_first         | 1     |
| Handler_read_key           | 3     |
| Handler_read_last          | 1     |
| Handler_read_next          | 0     |
| Handler_read_prev          | 0     |
| Handler_read_rnd           | 0     |
| Handler_read_rnd_next      | 1     |
| Handler_rollback           | 0     |
| Handler_savepoint          | 0     |
| Handler_savepoint_rollback | 0     |
| Handler_update             | 0     |
| Handler_write              | 1     |
+----------------------------+-------+
16 rows in set (0.00 sec)
...
Рейтинг: 0 / 0
20.09.2013, 18:28:28
    #38403137
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Средняя цена товара
Cygapb-007 http://sqlfiddle.com/#!2/3fa96/2 Разница в два раза, как и количество сканов таблицы.
...
Рейтинг: 0 / 0
20.09.2013, 18:50:57
    #38403165
javajdbc
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Средняя цена товара
Cygapb-007javajdbcнаверно будет быстрее найти среднее, затем
ближайший сверху (по индексу) и ближайший снизу (по индексу) и выбрать
самый "ближайший" из двух.

Ордер по функции --- точно полный сканНе уверен, что это быстрее :)
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
select * 
from (select @avg:=AVG(price)avg from Test)a
cross join (
   select * 
   from (
      (select *, ABS(price-@avg)delta from Test where price>=@avg order by price limit 1)
      union all
      (select *, ABS(price-@avg)delta from Test where price<=@avg order by price desc limit 1)
      ) u
   order by u.delta limit 1
   ) c



чисто по прикидке сравнить этот вариант (Б) и Ваш начальный (А):
оба получают АВГ(присе), затем (А) для каждого прайся
выс4итывает дельту и сортирует.
Ваероиант (Б) делает два быстрых поиска по индексу
(....where price>=@avg order by price limit 1....)
и сортирует два результата.

Т.е (Б) имеет лишний полный скан и полную сортировку
против (А) двух индекс поисков и сортировку двух результатов
...
Рейтинг: 0 / 0
20.09.2013, 19:15:05
    #38403181
Cygapb-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Средняя цена товара
miksoftCygapb-007 sqlfiddle.com/#!2/3fa96/2 Разница в два раза, как и количество сканов таблицы.На MySQL 5.6.6 разница не так ощутима... sqlfiddle.com/#!9/3fa96/15
Правда, с переменной так легко там не получилось, пришлось в отдельный запрос вынести.
...
Рейтинг: 0 / 0
20.09.2013, 19:35:30
    #38403188
Cygapb-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Средняя цена товара
javajdbcчисто по прикидке сравнить этот вариант (Б) и Ваш начальный (А):
оба получают АВГ(присе), затем (А) для каждого прайся
выс4итывает дельту и сортирует.
Ваероиант (Б) делает два быстрых поиска по индексу
(....where price>=@avg order by price limit 1....)
и сортирует два результата.

Т.е (Б)(A) имеет лишний полный скан и полную сортировку
против (А)(Б) двух индекс поисков и сортировку двух результатовНу в общем-то я ж не против ;-)
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Средняя цена товара / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]