|
FAQ: Нумерация строк и другие вопросы про использование переменных
|
|||
---|---|---|---|
#18+
Задача: Пронумеровать строки в запросе Достаточно часто возникает необходимость пронумеровать возвращаемые MySQL строки средствами самой базы данных. Решение: Код: plaintext 1.
В ряде случаев вы можете получить следующий ответ от MySQL: Код: plaintext
Тогда необходимо добавить алиас (псевдоним): Код: plaintext 1.
или воспользоваться механизмом присвоением нулевого значения переменной @i перед запросом, если такая возможность присутствует. Т.к. в случае если эти два запроса буду выполнены в разных подключениях, толку будет ноль, а вернее NULL . Код: plaintext 1.
Код: plaintext
... |
|||
:
Нравится:
Не нравится:
|
|||
02.08.2009, 19:10 |
|
FAQ: Нумерация строк и другие вопросы про использование переменных
|
|||
---|---|---|---|
#18+
Выборка нескольких последних записей в неких группах (а.к.а TOP N queries in categories). Допустим, имеется следуюшая задача : Появилась необходимость получить несколько строк, отсортированных по какому-то признаку и сгруппированных по какому-либо полю. Например, поиск 5 последних сообщений по каждой теме. Пробовал получать вот таким запросом: Код: plaintext 1. 2. 3. 4.
но почему-то он выдает ошибку, что LIMIT в подзапросах не поддерживается (вроде это очень простая операция, не понимаю почему ее нет?). Единственный выход какой я вижу - это UNION, но при большом количестве типов это будет не очень удобно. Как быть в данном случае, может есть какой-то вариант получше? Даже если ЛИМИТ проходит, последний запрос будет выпонятся для каждого значения колонки "type_a". О производительности здесь говорить не приходится. Решение с использованием переменных: 1. отсортировать таблицу по "type_a" и по "date_a DESC" 2. пронумеровать записи отдельно для кaждого значения "type_a" 3. выбрать первые 5 записи в каждой группе Реализация: 1. отсортировать таблицу по "type_a" и по "date_a DESC". Добавим селект для задания переменных @rownum -- для хранения текушего счетчика @typex -- для хранения текушего значения "type_a" Код: plaintext 1.
2. пронумеровать записи отдельно для кaждого значения "type" Код: plaintext 1. 2. 3. 4. 5. 6.
3. выбрать первые 5 записи в каждой группе Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9.
Примечания: @rownum:=1+least(0,@typex:=ta.type) гарантирует обновление @typex после проверки "if(@typex=ta.type..." Спасибо javajdbc ... |
|||
:
Нравится:
Не нравится:
|
|||
02.08.2009, 23:57 |
|
FAQ: Нумерация строк и другие вопросы про использование переменных
|
|||
---|---|---|---|
#18+
Пронумеровать поле таблицы "по-порядку" Код: plaintext 1. 2. 3. 4. 5.
... |
|||
:
Нравится:
Не нравится:
|
|||
03.08.2009, 09:17 |
|
FAQ: Нумерация строк и другие вопросы про использование переменных
|
|||
---|---|---|---|
#18+
Подробный разбор всех техник работы с переменными в запросе Advanced MySQL user variable techniques http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/ Финальный вариант X элементов из группы у него выглядит так: Код: plaintext 1. 2. 3. 4. 5. 6.
... |
|||
:
Нравится:
Не нравится:
|
|||
26.11.2009, 21:45 |
|
FAQ: Нумерация строк и другие вопросы про использование переменных
|
|||
---|---|---|---|
#18+
magicprinc Финальный вариант X элементов из группы у него выглядит так: Код: plaintext 1. 2. 3. 4. 5. 6.
Где гарантия, что порядок присвоений переменных @num и @type будет именно в том порядке как написано в запросе? По-моему этот запрос вообще недетерминирован и возвращает нужную нумерацию чисто случайно. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.02.2010, 12:07 |
|
FAQ: Нумерация строк и другие вопросы про использование переменных
|
|||
---|---|---|---|
#18+
Богдан Гоцкий, в принципе любая (за очень редким исключением) работа с переменными в резалт-сете, содержащем более одной записи, недетерминированна. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.02.2010, 12:27 |
|
FAQ: Нумерация строк и другие вопросы про использование переменных
|
|||
---|---|---|---|
#18+
Богдан Гоцкий Где гарантия, что порядок присвоений переменных @num и @type будет именно в том порядке как написано в запросе? По-моему этот запрос вообще недетерминирован и возвращает нужную нумерацию чисто случайно. Действительно, порядок выполнения в СЕЛЕКТ и в WHERE групе не определен -- теоретически. Практически я не видел доказаного случая неверного порядка. Етот вопрос известен и решается, правда через задницу, но все же решается. Посмотри второй пост в етой ветке, в самом конце: автор Примечания: @rownum:=1+least(0,@typex:=ta.type) гарантирует обновление @typex после проверки "if(@typex=ta.type..." ... |
|||
:
Нравится:
Не нравится:
|
|||
22.02.2010, 17:23 |
|
FAQ: Нумерация строк и другие вопросы про использование переменных
|
|||
---|---|---|---|
#18+
an0nymБогдан Гоцкий, в принципе любая (за очень редким исключением) работа с переменными в резалт-сете, содержащем более одной записи, недетерминированна. Странная сентенция.... если делать правильно, то все будет детерминировано.... если неправильно делать, то можно и пенис сломать... ... |
|||
:
Нравится:
Не нравится:
|
|||
22.02.2010, 17:29 |
|
FAQ: Нумерация строк и другие вопросы про использование переменных
|
|||
---|---|---|---|
#18+
javajdbc, я примерно это и имел в виду. :) ... |
|||
:
Нравится:
Не нравится:
|
|||
22.02.2010, 17:50 |
|
FAQ: Нумерация строк и другие вопросы про использование переменных
|
|||
---|---|---|---|
#18+
Модератор: Это FAQ-овый топик. Просьба не засорять его своими частными вопросами, для этого создавайте отдельные топики. Все, что не относится непосредственно к сабжу, зачищено. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.10.2011, 12:51 |
|
FAQ: Нумерация строк и другие вопросы про использование переменных
|
|||
---|---|---|---|
#18+
miksoftЭто FAQ-овый топик.Так может, в "важные" его? ... |
|||
:
Нравится:
Не нравится:
|
|||
27.10.2011, 15:31 |
|
FAQ: Нумерация строк и другие вопросы про использование переменных
|
|||
---|---|---|---|
#18+
tanglir, Вот понадобилось... а оно... :) Подход с переменными работает только при отсутствии сортировки в запросе, отличной от "по умолчанию" и нумерации только одной таблицы (без join!) Столкнулся с тем, что при задании сортировки в режиме DESC - нумерация переменными или совсем не производится, или пересортировывается также по DESC. Задача: оставить для каждого пользователя форума только по 10 ПОСЛЕДНИХ сообщений... то есть сообщения надо сгруппировать по пользователям, отсортировать в обратном порядке по дате и пронумеровать в прямом порядке (обратно дате!) и те, которые имеют номер в группе больше 10 - удалить нафиг... ну и ещё повеселило: Если таблица сообщений - сборка джойном из нескольких, то управление переменными в блоке where делается столько раз, сколько джойнов в сборке. То есть при двух таблицах (один джойн) - получаем только четные значения, при двух джойнах - кратные трем... и т.д. лечится включением всей сборки и сортировки во вложенный подселект. Но проблема в том, что у меня при записях "сообщений" больше 1млн и с десяток тысяч "пользователей"... внутренний подселект без временной таблицы - валится напрочь "табличка повреждена..." или как оно там... запись во временную табличку - около 2 минут... ... |
|||
:
Нравится:
Не нравится:
|
|||
04.04.2012, 19:36 |
|
FAQ: Нумерация строк и другие вопросы про использование переменных
|
|||
---|---|---|---|
#18+
Arhat109, да... переменные в мускл-е (и вообше в СКЛ) -- дело идеологически инородное... и требует осторожности в использовании... 1. было показано, что в зависимости от использовании-или-неиспользовании индексов на джоинте переменные евалюировались по разному. Т.е. для чистого СКЛ-а работа оптимизатора не влияет на результат, но может повлиять на вычисление переменные 2. единственый прямой способ добится однозначного порядка -- как вы отметили выше -- использование подселектов -- соединять таблицы внутри под-селекта но работать с переменными в следуюшем селекте. типа: 2a select ....переменные....from (select * from A,B where ...ORDER BY ...) 2b select ....переменные....from (select * from A,B where ....) ORDER BY ... наверное 2б будет правильнее 3. В сложных случаях -- подселекты являются проблемой ибо на подселекты нет индексов -- т.е. лефт джоинт на подселект будет медленым. 4. Выборка ТОП-Н всегда предпологает двойной проход: нумерация а потом отсечение -- я наблюдал случаи когда по нехватки памяти такие квери падали на хард-диск. А ето тормозило запрос на несколько порядков... На милионах записей это реально (я видел срыв на 400-600К на домашнем компе) 5. рекомендую создать новый топик по теме, поставить задачу, выдать пример данных, описать таблицы и индексы 6. Переменные -- не панацея, вполне может случится что работа через промежуточнуе таблицы будет быстрее... или с переменными но по 100К за раз (что б все в памяти)... ...или...надо посмотреть.. :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
08.04.2012, 04:16 |
|
FAQ: Нумерация строк и другие вопросы про использование переменных
|
|||
---|---|---|---|
#18+
javajdbc, не вижу смысла создавать отдельную тему. Надо оставить мой пост и ваш коммент "для ограничения применения", дабы народ не впадал в маразм, наступая на одни грабли. Этот пост можно потереть за ненадобностью. Решается всё достаточно легко предварительным созданием временной таблицы на базе подселектов только с нужными полями и навешиванием нужного количества индексов для последующей быстрой выборки с переменными... больше миллиона записей пролетает на удаление (суммарно с созданием временной таблицы) за 30-60 секунд... для разового запроса на чистку базы - мелочь. Даже если делать раз в день. Просто табличку мне надо было сразу создавать правильную, а не SELECT * FROM... :) Вполне достаточно только id,fkey,last_date ... |
|||
:
Нравится:
Не нравится:
|
|||
08.04.2012, 15:01 |
|
FAQ: Нумерация строк и другие вопросы про использование переменных
|
|||
---|---|---|---|
#18+
mahoune Выборка нескольких последних записей в неких группах (а.к.а TOP N queries in categories). Допустим, имеется следуюшая задача : Появилась необходимость получить несколько строк, отсортированных по какому-то признаку и сгруппированных по какому-либо полю. Например, поиск 5 последних сообщений по каждой теме. Пробовал получать вот таким запросом: Код: sql 1. 2. 3. 4. 5.
но почему-то он выдает ошибку, что LIMIT в подзапросах не поддерживается (вроде это очень простая операция, не понимаю почему ее нет?). Единственный выход какой я вижу - это UNION, но при большом количестве типов это будет не очень удобно. Как быть в данном случае, может есть какой-то вариант получше? Даже если ЛИМИТ проходит, последний запрос будет выпонятся для каждого значения колонки "type_a". О производительности здесь говорить не приходится. Решение с использованием переменных: 1. отсортировать таблицу по "type_a" и по "date_a DESC" 2. пронумеровать записи отдельно для кaждого значения "type_a" 3. выбрать первые 5 записи в каждой группе Реализация: 1. отсортировать таблицу по "type_a" и по "date_a DESC". Добавим селект для задания переменных @rownum -- для хранения текушего счетчика @typex -- для хранения текушего значения "type_a" Код: sql 1. 2.
2. пронумеровать записи отдельно для кaждого значения "type" Код: sql 1. 2. 3. 4. 5. 6. 7.
3. выбрать первые 5 записи в каждой группе Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Примечания: @rownum:=1+least(0,@typex:=ta.type) гарантирует обновление @typex после проверки "if(@typex=ta.type..." Спасибо javajdbc Код: sql 1. 2. 3. 4. 5. 6. 7.
и что никого не смутила ошибка??? первая група начнёт нумероваться с 2 а не с 1!!! и логически ясно, и лично только что проверил на мускле. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.05.2013, 14:02 |
|
FAQ: Нумерация строк и другие вопросы про использование переменных
|
|||
---|---|---|---|
#18+
alex564657498765453, по идее, первая група пройдет на строке: Код: sql 1.
...и нумерация пойдет с единицы. Двойка будет если самая первая група будет иметь название '_'. Если у вас по другому, приведите полный тест-кейс. Бывают случаи когда жоинты сбивали порядок вывода на блок СЕЛЕКТ. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.05.2013, 16:06 |
|
FAQ: Нумерация строк и другие вопросы про использование переменных
|
|||
---|---|---|---|
#18+
имеется ТАБЛИЦА - записи покупок Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
ЗАДАЧА Получить список самых активных покупателей и число их покупок. (если есть несколько человек, купивших больше всех, вывести нужно каждого) ожидаемый результат Код: plaintext 1. 2. 3. 4. 5.
при этом, не существует пользователя купившего больше чем 120. РЕШЕНИЕ без переменных Код: sql 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. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57.
РЕШЕНИЕ с использованием ПЕРЕМЕННЫХ Код: sql 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. 31. 32. 33. 34. 35. 36.
ПРЕИМУЩЕСТВА быстродействие - мы не делаем лишний запрос с группировкой и сортировкой. даже сама сортировка более медленный процесс, чем определение максимального значения пробежав по записям и обновляя значение переменной. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.06.2014, 16:54 |
|
FAQ: Нумерация строк и другие вопросы про использование переменных
|
|||
---|---|---|---|
#18+
Нашел упоминания когда рассматривалась одноранговая нумерация. Возникла необходимость внутри группы пронумеровать по возрастанию. Есть таблица сообщений (messages_wt), в этой таблице есть поле тем -TopicID_XF и поле сообщений - message_id, id1 - primary key Внутри одного топика надо пронумеровать сообщения по возрастанию message_id. Задачу решил так: (запрос работающий) Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
Но у меня есть подспудное чуство что зада решена очень коряво. Меня смущает мощный подзапрос. Подзапрос понадобился потому что в set не удается запихнуть присваивание. Собственно вопрос такой - можно ли решить эту задачу без подзапроса ? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.01.2018, 06:33 |
|
FAQ: Нумерация строк и другие вопросы про использование переменных
|
|||
---|---|---|---|
#18+
UPD: предыдущий запрос оказался нерабочим. Правильное решение без подзапроса: Код: sql 1. 2. 3. 4. 5. 6.
... |
|||
:
Нравится:
Не нравится:
|
|||
05.01.2018, 06:51 |
|
FAQ: Нумерация строк и другие вопросы про использование переменных
|
|||
---|---|---|---|
#18+
UlibkaНашел упоминания когда рассматривалась одноранговая нумерация. Возникла необходимость внутри группы пронумеровать по возрастанию. Гм... 7489069 ... |
|||
:
Нравится:
Не нравится:
|
|||
05.01.2018, 11:07 |
|
FAQ: Нумерация строк и другие вопросы про использование переменных
|
|||
---|---|---|---|
#18+
(по мотивам одной темы на одном форуме) Тонкость в присвоении инициализированным переменным нового значения. Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
fiddle ... |
|||
:
Нравится:
Не нравится:
|
|||
26.06.2020, 08:20 |
|
|
start [/forum/topic.php?fid=47&fpage=19&tid=1828497]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
53ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
131ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 241ms |
0 / 0 |