Forum Webscript.Ru

Общие => Базы данных => Тема начата: Alexandr от 20 Августа 2002, 08:37:37

Название: Выбрать 1 случайную запись.
Отправлено: Alexandr от 20 Августа 2002, 08:37:37
Необходимо сделать сабж. Сделал так:
SELECT anek FROM anek WHERE id=(1+FLOOR(MAX(id)*RAND()))
а он мне
1111 - Invalid use of group function - -1 rows affected

так
SELECT * FROM anek HAVING id=(1+FLOOR(MAX(id)*RAND()))
не робит правильно.
Мож кто подскажет оптимальный вариант, а я сделал так
SELECT anek FROM anek ORDER BY RAND() LIMIT 1
Но мне кажется это коряво.:insane:
Название: Выбрать 1 случайную запись.
Отправлено: Tronyx от 20 Августа 2002, 09:03:40
Цитировать
Но мне кажется это коряво.

А вроде не очень и коряво. Можно id самому генерировать (в скрипте), но это хуже...
Название: Выбрать 1 случайную запись.
Отправлено: Alexandr от 20 Августа 2002, 09:37:36
Цитировать
Можно id самому генерировать (в скрипте)

Нельзя. Т.к. придётся 2 запроса делать:
1 - Узнаём мах id (или весь массив id)
2 - Выбираем строку по случайному id.
Цитировать
А вроде не очень и коряво.

Да нет коряво. Т.к. используется ORDER и следовательно приходится выбирать сначала все записи, а далее их сортировать в случ. порядке и всё это ради одной записи.
Совсем др. дело первый запрос (если бы он работал), выбираем всего 1 запись и + используем примари кей.
Название: Выбрать 1 случайную запись.
Отправлено: ThE0ReTiC от 20 Августа 2002, 09:50:50
Цитировать
Узнаём мах id

Надо дергать весь массив. У тебя не обязательно id упорядоченно идет.
Название: Выбрать 1 случайную запись.
Отправлено: Alexandr от 20 Августа 2002, 10:44:20
Цитировать
Надо дергать весь массив.

Именно в моем скрипте/случае достаточно узнать мах.
[OFF]Я же упомянул это в скобках в пред. посте[/OFF]
Название: Выбрать 1 случайную запись.
Отправлено: Maniac от 20 Августа 2002, 11:51:36
А чем тебя два запроса не устраивают? IMHO тормозить сервер только из-за того, что хочется сделать красивее не шибко правильно
Название: Выбрать 1 случайную запись.
Отправлено: Alexandr от 20 Августа 2002, 12:04:50
Цитировать
А чем тебя два запроса не устраивают?

В принципе согласен.
2 запроса:
$num=mt_rand(1, mysql_result(mysql_query("SELECT MAX(id) FROM anek"), 0));
$text_anek=mysql_result(mysql_query("SELECT anek FROM anek WHERE id=".$num), 0);
Будут работать быстрее, чем
$text_anek=mysql_result(mysql_query("SELECT anek FROM anek ORDER BY RAND() LIMIT 1"), 0);

Просто хотелось что-нть...... если кто-то знает.
Название: Выбрать 1 случайную запись.
Отправлено: Меняздесьдавнонет от 20 Августа 2002, 15:12:11
Коряво???
А ты можешь привести хоть один аргумент этой корявости?
Кажется - это в церкви говорят. А здесь прфорум по программированию.

Вот с двумя запросами - это действительно коряво. Если анекдоты будут удаляться.
Название: Выбрать 1 случайную запись.
Отправлено: Maniac от 20 Августа 2002, 15:29:11
Цитировать
Вот с двумя запросами - это действительно коряво. Если анекдоты будут удаляться.


Это не коряво - это правильно и быстро.
А если анекдоты будут удаляться - надо читать внимательно постинги автора:
Цитировать
Именно в моем скрипте/случае достаточно узнать мах.
Название: Выбрать 1 случайную запись.
Отправлено: Меняздесьдавнонет от 20 Августа 2002, 16:36:45
Мда, не увидел.
просто уж больно редкий случай, когда id по порядку.
И как можно называть кривой конструкцию, которая была специально именно для таких случаев, введена в язык?
Название: Выбрать 1 случайную запись.
Отправлено: Alexandr от 20 Августа 2002, 16:57:38
Цитировать
просто уж больно редкий случай, когда id по порядку.

Основное что будет делаться - это извлечение из БД, следовательно мона пожертвовать скоростью добавления:
ALTER TABLE DROP id
...
INSERT .....
ALTER TABLE ADD id mediumint NOT NULL auto_increment UNSIGNED
Название: Выбрать 1 случайную запись.
Отправлено: Alexandr от 20 Августа 2002, 16:58:40
Цитировать
И как можно называть кривой конструкцию, которая была специально именно для таких случаев, введена в язык?

А эт ты о чём?
Название: Выбрать 1 случайную запись.
Отправлено: Maniac от 20 Августа 2002, 17:44:53
Цитировать
А эт ты о чём?

Это он про Limit
Название: Выбрать 1 случайную запись.
Отправлено: tserbis от 20 Августа 2002, 17:54:36
:-) это он про order by rand()
Название: Выбрать 1 случайную запись.
Отправлено: Alexandr от 20 Августа 2002, 18:02:23
Maniac
Цитировать
Это он про Limit

tserbis
Цитировать
это он про order by rand()

И что?
Название: Выбрать 1 случайную запись.
Отправлено: Меняздесьдавнонет от 20 Августа 2002, 18:10:25
Боже!
И ЭТО он называет НЕ корявым.
В этом мире что-то не так.

Саша.
Сделай так
$num=mt_rand(1, mysql_result(mysql_query("SELECT count(*) FROM anek"), 0));
$text_anek=mysql_result(mysql_query("SELECT anek FROM anek LIMIT $num,1), 0);
И избавь свою базу от грубого надругательства, извращенец.

(я оставлю за скобками, как ты будешь привязывать, к примеру голосование, к дропнутым id)
Название: Выбрать 1 случайную запись.
Отправлено: AlieN от 20 Августа 2002, 18:28:18
Цитировать
SELECT anek FROM anek ORDER BY RAND() LIMIT 1
Но мне кажется это коряво

А чего здесь корявого? :)
Название: Выбрать 1 случайную запись.
Отправлено: Меняздесьдавнонет от 20 Августа 2002, 18:44:50
AlieN
Не коряво, но работает действительно, медленно.
У меня 0,1 сек на базе в 500 записей исполнялся запрос.
А приведенные выше - 0,00
Название: Выбрать 1 случайную запись.
Отправлено: Alexandr от 21 Августа 2002, 08:14:16
Цитировать
$num=mt_rand(1, mysql_result(mysql_query("SELECT count(*) FROM anek"), 0));
$text_anek=mysql_result(mysql_query("SELECT anek FROM anek LIMIT $num,1), 0);

Ну я так-то в своих рассуждениях над этим и остановился.
Название: Выбрать 1 случайную запись.
Отправлено: rembo от 28 Августа 2002, 06:19:58
В данном случае по моему RomikChef прав
Цитировать
И как можно называть кривой конструкцию, которая была специально именно для таких случаев, введена в язык?

А это я вычитал в документации к мускулу:

     In MySQL Version 3.23, you can, however, do: `SELECT *
     FROM table_name ORDER BY RAND()\'

     This is useful to get a random sample of a set `SELECT * FROM
     table1,table2 WHERE a=b AND c
переводить надеюсь не надо.

Цитировать
Не коряво, но работает действительно, медленно.


А это смотря насколько часто приходится выполняеть такой запрос
Ведь конце концов за рандомить можно какое-нить целочисленное поле (id например) раз сортировка тратит столько времени. Хотя в базе аналогичного размера никакой разницы во времени исполнения я не заметил. В разных случаях колеблется от 0.00 до 0.02 на древнем селероне - разве это так важно.
Название: Выбрать 1 случайную запись.
Отправлено: Alexandr от 28 Августа 2002, 09:24:45
Цитировать
колеблется от 0.00 до 0.02 на древнем селероне - разве это так важно.

Ес-но. А если у тя таких запросов будет много?
Нахрена базу нагружать.
Название: Выбрать 1 случайную запись.
Отправлено: Tronyx от 28 Августа 2002, 10:29:03
Цитировать
Ес-но. А если у тя таких запросов будет много?
Нахрена базу нагружать.

А что мне делать? Вот мой запрос: "SELECT text FROM anek ORDER BY RAND() LIMIT 10" (так я достаю 10 случайных анекдотов), НО у меня значения id (авто_инкрементное поле) могут содержать "пробелы" и БД большая, думаю около 1500-2000 записей, так что вариант с двумя запросами мне не подходит...
Название: Выбрать 1 случайную запись.
Отправлено: Alexandr от 28 Августа 2002, 10:58:10
Если анекдоты удаляешь не часто, то может стоит подумать, как говорит RomikChef, над грубым надругательством, т.е. делать ALTER. Значительно, повысит эффективность, однако, если у тя id\'шник где-нть завязан, напр., голосование, то этот вариант сразу отпадает.
Название: Выбрать 1 случайную запись.
Отправлено: Antoxa от 04 Сентября 2002, 13:14:35
Цитировать
А что мне делать? Вот мой запрос: "SELECT text FROM anek ORDER BY RAND() LIMIT 10" (так я достаю 10 случайных анекдотов), НО у меня значения id (авто_инкрементное поле) могут содержать "пробелы" и БД большая, думаю около 1500-2000 записей, так что вариант с двумя запросами мне не подходит...

не подходит как раз вариант с твоим _одним_ запросом :)
сделай как говорит Ромик.
Название: Выбрать 1 случайную запись.
Отправлено: AlieN от 04 Сентября 2002, 14:20:44
ГЫ:
сам сейчас столкнулся с такой проблемой
select .... order by rand() limit 5 по базе в 5 мегов(25000 записей) тупит ужасно
я сделал вот так:

$num=mt_rand(1, mysql_result(mysql_query("SELECT count(*) FROM table"), 0))-5;
$result=mysql_query("select id from table limit $num,5");
Название: Выбрать 1 случайную запись.
Отправлено: Alexandr от 04 Сентября 2002, 16:03:43
Цитировать
$num=mt_rand(1, mysql_result(mysql_query("SELECT count(*) FROM table"), 0))-5;
$result=mysql_query("select id from table limit $num,5");

Глюк!!!!
Так надо:
$num=mt_rand(1, mysql_result(mysql_query("SELECT count(*) FROM table"), 0)-5);
$result=mysql_query("select id from table limit $num,5");