Составление запроса (взять всех за кого не голосовал)

Toxic-mt

Новичок
Составление запроса (взять всех за кого не голосовал)

На сайте организовано голосование за пользователя. Нужно выводить тех пользователей за которых еще не голосовал. Дополнительное условие: эти пользователи должны выводиться рандомно.

Исходные данные:
Таблица user
user_id .....

Таблица rating
rating_id rating_user_id_from rating_user_id_to rating_score

Есть подозрение что это делается через group by having, но опыта с having практически нет. А те варианты которые пробовал не подходят ((.

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

SELECT user_id
FROM user
WHERE user_id NOT IN (SELECT rating_user_id_to FROM rating WHERE rating_user_id_from=#user_id для которого смотрим#)
 

Toxic-mt

Новичок
Попробуйте составить такой запрос. Используя только IS NULL ничего не получится. Ведь нужны только те, за кого не голосовал текущий пользователь, а не все, за кого не голосовали.
 

Wicked

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

C001_UsEr

Новичок
ТС, дай кусок дампа phpmyadmin сюда, так будет нагляднее и удобнее.
 

Toxic-mt

Новичок
Автор оригинала: Wicked
а давай пробовать будешь ты?
Побольше уважения, мы еще не друзья, чтобы тыкать.

SELECT user_id FROM user LEFT JOIN rating ON user_id = ? WHERE ? IS NULL

По какому полю лефтджойнить. Ведь нам нужны как раз те user_id которые в табличке рейтинга не встречаются в связке from=#user_id текущего пользователя# to=#за кого голосуем#, а ведь возможен вариант что за пользователя еще никто ни разу не голосовал, и его user_id вообще в этой табличке нет.

-~{}~ 28.06.08 16:43:

CREATE TABLE `rating` (
`rating_id` int(10) unsigned NOT NULL auto_increment,
`rating_user_id_from` int(10) unsigned default NULL,
`rating_user_id_to` int(10) unsigned default NULL,
`rating_score` tinyint(4) default NULL,
`rating_created` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`rating_id`),
UNIQUE KEY `from_to_unique` (`rating_user_id_from`,`rating_user_id_to`)
)

CREATE TABLE `user` (
`user_id` int(10) unsigned NOT NULL auto_increment,
PRIMARY KEY (`user_id`)
)

упрощенный вариант

-~{}~ 28.06.08 16:55:

Получилось

SELECT user_id, rating.* FROM user
LEFT JOIN rating ON rating_user_id_to = user_id
WHERE user_id!=#текущий пользователь# AND (rating_user_id_to IS NULL OR rating_user_id_from!=#текущий пользователь#)
 

amadeus

Новичок
Не-а, уважаемый, не получилось. Видно, плохо тестировали. Ерунда полная получилась.

OR rating_user_id_from!=#текущий пользователь#

приведёт к тому, что даже если #текущий пользователь# голосовал за пользователя, и за этого же пользователя голосовали ещё 99 пользователей, то в результат запроса попадут 99 лишних строк. (Попробуйте побольше вариантов голосований друг за друга, многих за одного и т.д. и т.п. повводить, убедитесь).

последний пример можно так преобразовать, чтобы работал в соответствии с задачей
[SQL]
SELECT `user_id` , `rating`.`rating_score`
FROM `user`
LEFT JOIN `rating` ON `rating_user_id_to` = `user_id`
AND `rating_user_id_from` =#текущий пользователь#
WHERE `user_id` <>#текущий пользователь#
AND `rating_score` IS NULL
[/SQL]
но, я сомневаюсь, что на большом числе записей это будет эффективнее Вашего самого исходного варианта, попробуйте, может поможет.
А уж сортировку в случайном порядке здесь, наверное, лучше не заставлять БД выполнять.
 
Сверху