Модераторы: skyboy, MoLeX, Aliance, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> select where `x` in (1,2,3) order by 1,2,3 ? mysql 
V
    Опции темы
flashaa
Дата 28.6.2007, 01:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 796
Регистрация: 7.3.2006

Репутация: 2
Всего: 25



Привет всем. У меня вопрос, у меня есть некий набор айдишников, допустим (1,2,3,4).
Я извлекаю все строки таблицы , в которых айди входит в это множество:

select * from user where `id` in (1,2,3,4) 

А вот теперь соственно вопрос: как мне упорядочить мои строки по порядку следования айдишников в запросе? 
При чем айдишники могут идти совершенно случайно, например (3,2,4,1) и при запросе я хочу получить ответ в таком порядке:

3 юзер с третим айдишником вася
2 юзер со вторым айдишником петя
4 юзер с четвертым айдишником котя
1 юзер с первым айдишником саша

Можно ли это вообще и если да, то как?
PM MAIL   Вверх
mishaSL
Дата 28.6.2007, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1046
Регистрация: 10.1.2007
Где: Санкт-Петербург

Репутация: 7
Всего: 54



flashaa, нормального решения этого нет. А собственно зачем это? Лучше упорядочить строку с id которая идет в запрос. 


--------------------
Лучший способ научиться программированию - это посмотреть как это делают другие...
PM MAIL   Вверх
SelenIT
Дата 28.6.2007, 19:03 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


баг форума
****


Профиль
Группа: Завсегдатай
Сообщений: 3996
Регистрация: 17.10.2006
Где: Pale Blue Dot

Репутация: 9
Всего: 401



Как вариант,
Код

select * from user where `id` in (3,2,4,1) order by FIND_IN_SET(`id`, '3,2,4,1')



--------------------
Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму!
PM MAIL   Вверх
sTa1kEr
Дата 28.6.2007, 19:07 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 9
Всего: 146



flashaa, упорядочнить можно следующим образом
Код

SELECT * FROM user WHERE `id` IN (1,2,3,4) ORDER BY FIELD(`id`, 3, 2, 4, 1);

PM MAIL   Вверх
flashaa
Дата 28.6.2007, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 796
Регистрация: 7.3.2006

Репутация: 2
Всего: 25



Cпасибо большое.
А упорядочить надо так потому сначала было несколько пользователей объединенных по общему полю (допустим user.active_room) - эти пользователи являлись участниками ОДНОЙ общей сущности,  и выборка этих пользователей осуществлялась значению ПОЛЬЗОВАТЕЛЬСКОГО поля.
Далее эта сущность становится недействительна, допустим закрывается некая комната переговоров с этими пользователями - 
cами пользователи высвобождаются  - их поле active_room становится нейтральным, но при этом необходимо сохранить для истории кто из пользователей был в этой комнате и в каком порядке на момент закрытия -
для этой цели я не придумал ничего другого как взять все АЙДИ этих пользователей, собрать в масиив, затем
в строку с разделителями "|" - получил  строку 4|3|2|1|5 и запихал ее в поле room.history закрытой комнаты.

Теперь, чтобы посмотреть кто из пользователей был в той комнате на момент закрытия, скрипт выполняет обратную операцию - получает этот набор айдишников из строки 4|3|2|1|5, 
далее  с помощью запроса 
Код

select * from user where `id` in (4,3,2,1,5) 

 получает эту выборку пользователей. Порядок важен , потому и возник данный вопрос.

Это сообщение отредактировал(а) flashaa - 28.6.2007, 19:26
PM MAIL   Вверх
mishaSL
Дата 28.6.2007, 20:28 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1046
Регистрация: 10.1.2007
Где: Санкт-Петербург

Репутация: 7
Всего: 54



ИМХО, тогда лучше сделать отдельную таблицу history с примерно такой структурой:
Код

history_id    int
room_id       int -  ID комнаты
user_id        int -  ID пользователя
order_user  int -  порядок пользователей
// т.д. другие необходимые поля


И выборка нужных данных будет гораздо проще и быстрее.


--------------------
Лучший способ научиться программированию - это посмотреть как это делают другие...
PM MAIL   Вверх
flashaa
Дата 28.6.2007, 23:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 796
Регистрация: 7.3.2006

Репутация: 2
Всего: 25



не совсем понял, что от этого изменится? ведь все равно каждой комнате будет соотвествовать несколько (в общем случае) пользователей и чтобы уместить информацию об ОДНОЙ комнате в 1 строку, придется пихать эти айди опять таки в какое-то одно поле - аналогично моему решению, только с использованием доп. таблицы. Или может быть я вас не правильно понимаю?

Добавлено через 5 минут и 25 секунд
Кстати тут же позвольте спросить попутный вопрос: 
как лучше сделать? - много простых запросов к бд или один всеобмлющий запрос и его разбор в PHP.

Это сообщение отредактировал(а) flashaa - 28.6.2007, 23:10
PM MAIL   Вверх
Golda
Дата 28.6.2007, 23:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 26.3.2007
Где: Ариель, Израиль

Репутация: 6
Всего: 42



flashaa, в примере mishaSL на одну комнату приходится столько записей, сколько в ней было пользователей. А их порядок определяется полем order_user. И умещать информацию об одной комнате в одну строку не приходится. Запрос:

Код

SELECT user.* 
FROM history AS h INNER JOIN user AS u ON h.user_id = u.id
WHERE h.room_id = 2
ORDER BY h.order_user


Добавлено через 3 минуты и 26 секунд
Как правило, один запрос сработает быстрее. Как в самой в базе, так и из-за того, что не придется по нескольку раз передавать данные между базой и скриптом.


--------------------
"For every problem, there exists a simple and elegant solution which is absolutely wrong." -- J. Wagoner, U.C.B. Mathematics
PM MAIL   Вверх
sergejzr
Дата 28.6.2007, 23:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 2
Всего: 360



Похожая ситуация:
происходит выборка постов на форуме, сортировка идёт например по времени. Идентификаторы результата сохраняются, чтобы не надо было каждый раз производить поиск, когда "листаешь" результаты. При этом при каждом "листании" приходится сортировать заного и конечно это лишняя работа. Тем более, что индекс по времени уже не использовать. 


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
sTa1kEr
Дата 29.6.2007, 00:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 9
Всего: 146



Цитата(Golda @  28.6.2007,  23:21 Найти цитируемый пост)
Как правило, один запрос сработает быстрее. Как в самой в базе, так и из-за того, что не придется по нескольку раз передавать данные между базой и скриптом. 

Не всегда. К тому же часто (в отношении хостеров, правельнее сказать почти всегда) БД и веб-сервер находятся на одной физической машине и передача данных занимает минимальное время. В данном случае все зависит от конкретного запроса. Так например, объединение таблиц не по индексным полям займет очень много ресурсов. В тоже время выборка из одной таблицы по примари будет максимально быстрой.
Цитата

Some examples of queries that are very fast: 

SELECT COUNT(*) FROM tbl_name;

SELECT MIN(key_part1),MAX(key_part1) FROM tbl_name;

SELECT MAX(key_part2) FROM tbl_name
  WHERE key_part1=constant;

SELECT ... FROM tbl_name
  ORDER BY key_part1,key_part2,... LIMIT 10;

SELECT ... FROM tbl_name
  ORDER BY key_part1 DESC, key_part2 DESC, ... LIMIT 10;

Очень часто максимальной производительности можно достичь при помощи хранимых процедур. Т.е. все быстрые и маленькие выборки + некоторая логика и выборка из объемной таблицы по индексированным полям будет происходить в БД.

Это сообщение отредактировал(а) sTa1kEr - 29.6.2007, 00:01
PM MAIL   Вверх
Golda
Дата 29.6.2007, 00:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 26.3.2007
Где: Ариель, Израиль

Репутация: 6
Всего: 42



По поводу хранимых процедур согласна на 100%. Несколько раз в postgres ощутимо уменьшала время таким образом. Жаль, в MySQL недоступно


--------------------
"For every problem, there exists a simple and elegant solution which is absolutely wrong." -- J. Wagoner, U.C.B. Mathematics
PM MAIL   Вверх
flashaa
Дата 29.6.2007, 00:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 796
Регистрация: 7.3.2006

Репутация: 2
Всего: 25



А LIMIT сильно повышает производительность?

И после вот таких запросов 

Код

SELECT COUNT(*) FROM tbl_name;


Как извлекать результат? Так же как и без COUNT  ? т.е. mysql_result($r,$i,"user_name") ? Только теперь вместо набор юзернеймов будет одно число , которое показывает их количество?

Это сообщение отредактировал(а) flashaa - 29.6.2007, 00:26
PM MAIL   Вверх
sTa1kEr
Дата 29.6.2007, 00:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 9
Всего: 146



Цитата(Golda @  29.6.2007,  00:12 Найти цитируемый пост)
Жаль, в MySQL недоступно 

Почему же? Начиная с 5ой версии доступно.
Stored Procedures and Functions
Цитата

А LIMIT сильно повышает производительность?

Да, если не используется сложная выборка.

Цитата(flashaa @  29.6.2007,  00:26 Найти цитируемый пост)
Как извлекать результат? Так же как и без COUNT  ? т.е. mysql_result($r,$i,"user_name") ?

Нет, в данном случае для поля надо задавать Alias.
Код

$r = mysql_query("SELECT COUNT(*) AS count_user_name FROM tbl_name");
$count = mysql_result($r,$i,"count_user_name");

Или обращаться по индексу.


Это сообщение отредактировал(а) sTa1kEr - 29.6.2007, 00:44
PM MAIL   Вверх
sergejzr
Дата 29.6.2007, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 2
Всего: 360



Цитата(flashaa @  29.6.2007,  00:00 Найти цитируемый пост)
поэтому не буду делать новую тему, а спрошу здесь..

Модератор: Пожалуйста, один топик - один вопрос.!!


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
flashaa
Дата 29.6.2007, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 796
Регистрация: 7.3.2006

Репутация: 2
Всего: 25



Цитата(Golda @ 28.6.2007,  23:21)
flashaa, в примере mishaSL на одну комнату приходится столько записей, сколько в ней было пользователей. А их порядок определяется полем order_user. И умещать информацию об одной комнате в одну строку не приходится. Запрос:

Код

SELECT user.* 
FROM history AS h INNER JOIN user AS u ON h.user_id = u.id
WHERE h.room_id = 2
ORDER BY h.order_user


А если один пользователь был во многих комнатах? 
Тогда придётся скидывать каждогого пользователя из каждой комнаты в отдельную строку - очень много лишней информации
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Базы Данных | Следующая тема »


 




[ Время генерации скрипта: 0.0759 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.