| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > PHP: Базы Данных > select where `x` in (1,2,3) order by 1,2,3 ? |
| Автор: flashaa 28.6.2007, 01:03 |
| Привет всем. У меня вопрос, у меня есть некий набор айдишников, допустим (1,2,3,4). Я извлекаю все строки таблицы , в которых айди входит в это множество: select * from user where `id` in (1,2,3,4) А вот теперь соственно вопрос: как мне упорядочить мои строки по порядку следования айдишников в запросе? При чем айдишники могут идти совершенно случайно, например (3,2,4,1) и при запросе я хочу получить ответ в таком порядке: 3 юзер с третим айдишником вася 2 юзер со вторым айдишником петя 4 юзер с четвертым айдишником котя 1 юзер с первым айдишником саша Можно ли это вообще и если да, то как? |
| Автор: mishaSL 28.6.2007, 18:49 |
| flashaa, нормального решения этого нет. А собственно зачем это? Лучше упорядочить строку с id которая идет в запрос. |
| Автор: SelenIT 28.6.2007, 19:03 | ||
Как вариант,
|
| Автор: sTa1kEr 28.6.2007, 19:07 | ||
flashaa, упорядочнить можно следующим образом
|
| Автор: flashaa 28.6.2007, 19:24 | ||
| Cпасибо большое. А упорядочить надо так потому сначала было несколько пользователей объединенных по общему полю (допустим user.active_room) - эти пользователи являлись участниками ОДНОЙ общей сущности, и выборка этих пользователей осуществлялась значению ПОЛЬЗОВАТЕЛЬСКОГО поля. Далее эта сущность становится недействительна, допустим закрывается некая комната переговоров с этими пользователями - cами пользователи высвобождаются - их поле active_room становится нейтральным, но при этом необходимо сохранить для истории кто из пользователей был в этой комнате и в каком порядке на момент закрытия - для этой цели я не придумал ничего другого как взять все АЙДИ этих пользователей, собрать в масиив, затем в строку с разделителями "|" - получил строку 4|3|2|1|5 и запихал ее в поле room.history закрытой комнаты. Теперь, чтобы посмотреть кто из пользователей был в той комнате на момент закрытия, скрипт выполняет обратную операцию - получает этот набор айдишников из строки 4|3|2|1|5, далее с помощью запроса
получает эту выборку пользователей. Порядок важен , потому и возник данный вопрос. |
| Автор: mishaSL 28.6.2007, 20:28 | ||
ИМХО, тогда лучше сделать отдельную таблицу history с примерно такой структурой:
И выборка нужных данных будет гораздо проще и быстрее. |
| Автор: flashaa 28.6.2007, 23:09 |
| не совсем понял, что от этого изменится? ведь все равно каждой комнате будет соотвествовать несколько (в общем случае) пользователей и чтобы уместить информацию об ОДНОЙ комнате в 1 строку, придется пихать эти айди опять таки в какое-то одно поле - аналогично моему решению, только с использованием доп. таблицы. Или может быть я вас не правильно понимаю? Добавлено через 5 минут и 25 секунд Кстати тут же позвольте спросить попутный вопрос: как лучше сделать? - много простых запросов к бд или один всеобмлющий запрос и его разбор в PHP. |
| Автор: Golda 28.6.2007, 23:21 | ||
flashaa, в примере mishaSL на одну комнату приходится столько записей, сколько в ней было пользователей. А их порядок определяется полем order_user. И умещать информацию об одной комнате в одну строку не приходится. Запрос:
Добавлено через 3 минуты и 26 секунд Как правило, один запрос сработает быстрее. Как в самой в базе, так и из-за того, что не придется по нескольку раз передавать данные между базой и скриптом. |
| Автор: sergejzr 28.6.2007, 23:42 |
| Похожая ситуация: происходит выборка постов на форуме, сортировка идёт например по времени. Идентификаторы результата сохраняются, чтобы не надо было каждый раз производить поиск, когда "листаешь" результаты. При этом при каждом "листании" приходится сортировать заного и конечно это лишняя работа. Тем более, что индекс по времени уже не использовать. |
| Автор: Golda 29.6.2007, 00:12 |
| По поводу хранимых процедур согласна на 100%. Несколько раз в postgres ощутимо уменьшала время таким образом. Жаль, в MySQL недоступно |
| Автор: flashaa 29.6.2007, 00:26 | ||
| А LIMIT сильно повышает производительность? И после вот таких запросов
Как извлекать результат? Так же как и без COUNT ? т.е. mysql_result($r,$i,"user_name") ? Только теперь вместо набор юзернеймов будет одно число , которое показывает их количество? |
| Автор: sTa1kEr 29.6.2007, 00:43 | ||||||
Почему же? Начиная с 5ой версии доступно. http://dev.mysql.com/doc/refman/5.0/en/stored-procedures.html
Да, если не используется сложная выборка.
Нет, в данном случае для поля надо задавать Alias.
Или обращаться по индексу. |
| Автор: sergejzr 29.6.2007, 12:38 |
Модератор: Пожалуйста, один топик - один вопрос.!! |
| Автор: flashaa 29.6.2007, 14:50 | ||||
А если один пользователь был во многих комнатах? Тогда придётся скидывать каждогого пользователя из каждой комнаты в отдельную строку - очень много лишней информации |
| Автор: mishaSL 29.6.2007, 16:57 |
| flashaa, эта информация не лишняя. Это называется нормализация структуры БД. С такой структурой БД можно будет одним запросом выбирать необходимую информацию, причем достаточно быстро. Когда вы храните информацию в виде id1|id2|id3 в текстовом поле, то есть очевидные минусы: 1. для выборки необходимо минимум два запроса: выбрать эту строку -> обработать результат -> выброть необходимые данные по пользователям. 2. Вы изначально не даете себе возможность хранить другие дополнительные данные, к примеру дату закрытия. Или есть появится необходимость в функции повторного открытия комната, то вам будет необходимо всего лишь добавить в таблицу с историей поле дата и вы сможете хранить информацию о любом кол-ве закрытия комнат. 3. с отдельной таблицей у вас появляется возможность бысторого вывода статистики, к примеру: в каких комнатах пользователь участвовал и т.д. |
| Автор: flashaa 29.6.2007, 17:29 | ||||
1. Тут согласен 2. Дата закрытия, открытия - параметры самой комнаты, они хранятся в соотв. полях таблицы комнат. Исходя из задачи: открывать закрытую комнату нельзя. 3. А вывод статистики в каких комнатах участвовал человек у меня происходит
само поле history выглядит как "(id1,id2,id3)" Хотя вы меня переубедили, лучще сделаю лишнюю таблицу, сделаю бОльший запрос по вставке, зато все запросы по выборке упростятся а PHP-код упроститься и при вставке и при выборке. |
| Автор: mishaSL 29.6.2007, 17:32 | ||
|
| Автор: flashaa 29.6.2007, 19:43 | ||||||||
Что-то не работает вот такой запрос:
вот так извлекаю:
запрос проходит нормально. а вот извлечение выдает: Column count doesn't match value count at row 1 |
| Автор: sTa1kEr 29.6.2007, 20:16 |
Это ошибка бывает при вставке данных. Вы уверенны, что она происходит именно в этом запросе? Делайте проверки после каждого запроса. Вопросительный знак - это вы так колонку назвали? Оригинально |
| Автор: flashaa 29.6.2007, 22:19 |
| Да, ошибка означает, что кол-во заявленных полей не соотвествует кол-ву значений, моя неправда.. |
| Автор: Golda 30.6.2007, 09:20 |
| sTa1kEr, спасибо за информацию о stored procedures в mysql. Упустила это событие |