|
|
|
запрос не для впечатлительных, +21
|
|||
|---|---|---|---|
|
#18+
Дано : таблицы Countries, Customers, Sales, Products , они имеют ключи country_id, customer_id, sale_id,product_id . Отношение Страны - покупатели - один ко многим, покупатели - покупка - один ко многим, продукты - покупка один ко многим. Цена товара product_price лежит в Products, там же лежит категории товаров(1,2,3). Countries содержит так же и имена стран. Найти : распределение общего количества покупок категории "1" с распределением по странам (т.е. распределение по странам, в которых проживают клиенты), в конечной выборке оставить те страны, в которых общая сумма покупок выше, чем средняя сумма по всему миру. Неудачное решение: Вот код: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Призыв : помогите! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.11.2013, 15:53:20 |
|
||
|
запрос не для впечатлительных, +21
|
|||
|---|---|---|---|
|
#18+
aleXVoipp, Первая задача -- подсчитать неколько агрегатов по странам --- вполне обычное задание -- неколько джоинтов , SUM, AVG, COUNT и груп бу по стране. А вот второе задание -- выбрать только те страны у которых авераже выше среднего -- надо подумать. Простейшее решение -- материализовать (можно как MEMORY) таблицу из первого запроса , потом отдельно посчитать среднее и отдельно отобрать страны которые выше среднего. Если вам нужен ресультат -- то сделайте через промежуточную таблицу. Если вы хотите поизврашатся (осторожно, BDSM, +21), кажется есть варианты где не надо будет материализовать исходный результат и не надо будет его два раза просчитытвать. Эти варианты: WITH ROLL UP и/или один-два вложеных запроса на переменных. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.11.2013, 19:47:52 |
|
||
|
запрос не для впечатлительных, +21
|
|||
|---|---|---|---|
|
#18+
javajdbc, чуть больше года назад решал подобные задачи... не заметил чего-то "сильно сложного"... правда мне 50+ :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.11.2013, 20:08:25 |
|
||
|
запрос не для впечатлительных, +21
|
|||
|---|---|---|---|
|
#18+
Arhat109, ок, вот тестовая задача: имеестся данные которые получаются следуюшим кодом: select 1 a, sleep(2) b from dual union select 2, sleep(2) from dual union select 3, sleep(2) from dual Надо одним селектом выбрать за быстрее чем 6.5 секунд записи где колонка "а" выше среднего. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.11.2013, 20:37:02 |
|
||
|
запрос не для впечатлительных, +21
|
|||
|---|---|---|---|
|
#18+
javajdbc, Ну блин встрял... я чё, помню "как"? (50+) :) Есть дамп с решением (сохранился ещё), на выходных поставлю Мускуль и попробую развернуть, вышлю. Просто он около 7гектар и на моей машинке будет разворачиваться не меньше суток. А сейчес - лениво, да и работа в другой тематике (чистое PHP). Ход рассуждений был примерно такой: 1. Считать среднее всё одно надо, а стало быть без группировки ваших записей - никак. Считать скользящее среднее "на лету" в переменной - бессмысленно, поскольку окончательный результат все одно будет последним. 2. Проблема в том, чтобы пройти одним циклом в одном селекте. Стало быть вместе с подсчетом среднего, надо "как-то" заполучить "что-то ещё" что потом или сразу отдать как результат или отсечь из него то, что будет результатом. 3. Всё что "можно" как "что-то ещё" - GROUP_CONCAT() явно или в переменных. Но, если "чего-то" группировать в текст, то по-сути, мы "потом" будем просматривать его на предмет выборки, что фактически есть материализация, только очень медленно. Проще материализовать и посчитать сначала среднее, потом с ним и пробежаться по времянке. 4. С другой стороны, если предварительно отсортировать данные по убыванию, то скользящее среднее будет все время уменьшаться, и записи, больше-равные этому значению - действительны и их можно загонять в выборку. 5. К сожалению, скользящее среднее может сильно "упасть" к концу выборки и записи могут быть необосновано пропущены. Сортировка по возрастанию, приводит к той же проблеме "наоборот". Считать "одновременно" - не получается, сортировка - одна "или та или другая". Стало быть, "потеряшек" как-то надо "возвращать в строй" или "удалять из него" (смотря куда сортируем). Стало быть "результат" - также "копим" в переменной, которую можно чистить. Отсюда - полезна только сортировка по возрастанию. :) То есть заворачиваем ваш запрос в сортировку по возрастанию и считаем в переменной скользящее среднее, накапливая результат тоже в переменной. Условие отбора - значение меньше-равно (не больше) скользящего среднего (выкашиваем из переменной substring(), locate(), find_in_set(), etc.). В результат выдаем среднее и группированный список оставшихся значений из переменной через запятую. Если надо записи "по отдельности", то джойним с нумерацией и разделяем список на записи по запятым. Не сказать что "очень быстро" но за один проход. При больших наборах материализация с индексированием может стать быстрее. Как-то так. (это чтобы не подумалось что "слил" :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2013, 07:26:49 |
|
||
|
запрос не для впечатлительных, +21
|
|||
|---|---|---|---|
|
#18+
Arhat109, Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. Ответ за 5.01 сек: 4,14,13 5,15,13 Груп бы по ИД с роллапом заменил вашу идею на переменных собрать среднее значение. Потом всеже пришлось пройтись переменной -- разнести среднее занчение по всем записям. Неожидано сработал HAVING без GROUP BY и без агрегатов. (Надеюсь Яростный Меч и МастерЗив не увидят этого безобразия :-) ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2013, 08:25:56 |
|
||
|
запрос не для впечатлительных, +21
|
|||
|---|---|---|---|
|
#18+
javajdbc, Зато я увидел это безобразие. И это действительно оно. Применять having без group by - форменное безобразие. (косяк парсера движка ваще-то!) :) Это раз. И второе: посмотрите на то задание что выдали мне и свой внутренний селект и найдите разницу. Почто мне выдали без преднумерации? :) И третье. Красиво в целом. Идея группировки по негруппирующему столбцу и подсчет итогов... не подумал. Да и в моем решении так не использовалось. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2013, 10:17:05 |
|
||
|
запрос не для впечатлительных, +21
|
|||
|---|---|---|---|
|
#18+
Arhat109, Кстати WHERE av > @n -- тоже должно сработать. Кузявее. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2013, 10:19:56 |
|
||
|
запрос не для впечатлительных, +21
|
|||
|---|---|---|---|
|
#18+
Arhat109Применять having без group by - форменное безобразие. (косяк парсера движка ваще-то!) :)Почему косяк? в документации не запрещено. Косвенно даже разрешено: http://dev.mysql.com/doc/refman/5.5/en/select.html The SQL standard requires that HAVING must reference only columns in the GROUP BY clause or columns used in aggregate functions. However, MySQL supports an extension to this behavior, and permits HAVING to refer to columns in the SELECT list and columns in outer subqueries as well. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2013, 10:26:49 |
|
||
|
запрос не для впечатлительных, +21
|
|||
|---|---|---|---|
|
#18+
miksoft, Да завсегда можно обозвать косяк фичей и радоваться. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2013, 10:33:59 |
|
||
|
запрос не для впечатлительных, +21
|
|||
|---|---|---|---|
|
#18+
Arhat109, Ну и кстати, селект-то один, а проходов - два. Сначала считаем среднее (через rollup), а потом отсекаем лишнее. У меня - один проход, но со строковыми функциями, что тоже далеко не айс. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2013, 10:36:12 |
|
||
|
запрос не для впечатлительных, +21
|
|||
|---|---|---|---|
|
#18+
Arhat109Arhat109, Ну и кстати, селект-то один, а проходов - два. Сначала считаем среднее (через rollup), а потом отсекаем лишнее. У меня - один проход, но со строковыми функциями, что тоже далеко не айс. :) Ну 1,2,3,4,5 -- это просто ИД, необязательно упорядочмые, да без них ролап бы не сработал как надо. А проходов должно быть два полюбому: собрать среднее и отсечь по среднему. Даже собирать все в строку -- придется все равно строку разбирать на больше-меньше. вопшем, как ТС и заказывал, SQL-порнография +21 :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2013, 22:35:01 |
|
||
|
запрос не для впечатлительных, +21
|
|||
|---|---|---|---|
|
#18+
javajdbc, Не совсем. В моем варианте - один проход. Там просто гемморой с переменными и их обработка тут же на лету. Сильно не уверен что он быстрее вашего роллапа. Не красивее и сложнее - точно. :) В целом, да. Скуль-порнография-21+. Но, все равно, "не особо сложно". :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2013, 07:44:13 |
|
||
|
запрос не для впечатлительных, +21
|
|||
|---|---|---|---|
|
#18+
Arhat109, ok! :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2013, 19:57:00 |
|
||
|
|

start [/forum/topic.php?fid=47&msg=38461330&tid=1835732]: |
0ms |
get settings: |
8ms |
get forum list: |
14ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
30ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
38ms |
get tp. blocked users: |
1ms |
| others: | 204ms |
| total: | 310ms |

| 0 / 0 |
