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

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

Помогите с запросом.
...
Рейтинг: 0 / 0
Средняя цена товара
    #38402892
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
select *
from test
order by ABS(price-(select AVG(price) from test))
limit 1
...
Рейтинг: 0 / 0
Средняя цена товара
    #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
Средняя цена товара
    #38403095
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SharuPoNemnoguнужно найти среднее значение price. НО! Не просто высчитать среднее, а некий СУЩЕСТВУЮЩИЙ price? который более менее посредине между min и max.Может, вам нужна медиана ?
...
Рейтинг: 0 / 0
Средняя цена товара
    #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
Средняя цена товара
    #38403132
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Средняя цена товара
    #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
Средняя цена товара
    #38403137
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cygapb-007 http://sqlfiddle.com/#!2/3fa96/2 Разница в два раза, как и количество сканов таблицы.
...
Рейтинг: 0 / 0
Средняя цена товара
    #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
Средняя цена товара
    #38403181
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftCygapb-007 sqlfiddle.com/#!2/3fa96/2 Разница в два раза, как и количество сканов таблицы.На MySQL 5.6.6 разница не так ощутима... sqlfiddle.com/#!9/3fa96/15
Правда, с переменной так легко там не получилось, пришлось в отдельный запрос вынести.
...
Рейтинг: 0 / 0
Средняя цена товара
    #38403188
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javajdbcчисто по прикидке сравнить этот вариант (Б) и Ваш начальный (А):
оба получают АВГ(присе), затем (А) для каждого прайся
выс4итывает дельту и сортирует.
Ваероиант (Б) делает два быстрых поиска по индексу
(....where price>=@avg order by price limit 1....)
и сортирует два результата.

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


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