Нужно подобие дополнительного условия WHERE

SaBo

Новичок
Нужно подобие дополнительного условия WHERE

Таблица text:

tid int(10) auto_increment
uid int(10)
name varchar(30)
contest tinyint(1)

Таблица votes:

vid int(10) auto_increment
uid int(10)
tid int(10)
val int(1)
date datetime
cover int(10)
auto tinyint(1)

Есть такой запрос:

SELECT `v`.`vid`, `t`.`tid` FROM `votes` AS `v` INNER JOIN `text` AS `t` ON v.uid = t.uid WHERE (v.cover = 0) AND (t.contest = 1) AND (v.uid != '6') ORDER BY `v`.`date` ASC LIMIT 0,1

Нужно добавить ещё одно условие по которому будет выбираться та строка в таблице votes если в ней (в этой таблице) не существует ещё одной строки с (v.tid = выбранному v.tid AND v.uid = 6). Как это сделать?

-~{}~ 27.01.10 16:30:

Вроде бы сам разобрался.
Нужно юзать в WHERE ... AND NOT EXISTS (SELECT ... FROM `votes` AS `vo` WHERE ...)
 

dimagolov

Новичок
SaBo, посмотри explain. что-то мне кажется, что подзапрос будет выполняться для каждой строки основной выборки, а это не просто выборка, а суперпозиция двух таблиц.
 

SaBo

Новичок
Автор оригинала: dimagolov
SaBo, посмотри explain. что-то мне кажется, что подзапрос будет выполняться для каждой строки основной выборки, а это не просто выборка, а суперпозиция двух таблиц.
EXPLAIN выдал следующее:

+----+-----------------------------------+-------+------+--------------------+--------+-----------+--------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-----------------------------------+-------+------+--------------------+--------+-----------+--------+-------+----------------------------------------------+
| 1 | PRIMARY | v | ALL | NULL | NULL | NULL | NULL | 5 | Using where; Using temporary; Using filesort |
| 1 | PRIMARY | t | ALL | NULL | NULL | NULL | NULL | 5 | Using where; Using join buffer |
| 2 | DEPENDENT SUBQUERY | vo | ALL | NULL | NULL| NULL | NULL | 5 | Using where |
+----+-----------------------------------+-------+------+--------------------+--------+-----------+--------+-------+----------------------------------------------+


Вот сам запрос:

EXPLAIN SELECT `v`.`vid`, `t`.`tid` FROM `votes` AS `v` INNER JOIN `text` AS `t` ON v.uid = t.uid WHERE (v.cover = 0) AND (t.contest = 1) AND (v.uid != '6') AND (NOT EXISTS (SELECT `vo`.`vid` FROM `votes` AS `vo` WHERE (vo.uid = '6') AND (vo.tid = t.tid) LIMIT 1)) ORDER BY `v`.`date` ASC;

Я так предполагаю, что в случае с table vo должно быть затронуто только две строчки, так как под первое условие попадает только две строчки, но там всё равно 5 (то есть все строки, которые есть в таблице). Может быть можно как-то оптимизировать этот запрос?
 

dimagolov

Новичок
ты объясни что у тебя за сущности и что ты хочешь хранить-запрашивать
 

SaBo

Новичок
В таблице text лежат тексты пользователей
tid - ID текста
uid - ID автора текста
name - название текста
contest - выставлен ли текст на конкурс

в таблицу votes записываются голоса пользователей. Пользователь может голосовать за выставленный на голосование текст только один раз. Но при этом надо убедиться, что автор выставленного на голосование текста уже когда-то голосовал за чужой текст.
При этом за выставленный на голосование текст автора можно проголосовать столько же раз, сколько проголосовал сам автор этого текста. Как-то так.
 

SaBo

Новичок
user1 разместил текст1.1 на голосование.
user1 проголосовал за текст2.1 пользователя user2
user1 проголосовал за текст3.1 пользователя user3

Теперь за текст1.1 может проголосовать два разных пользователя.
 

dimagolov

Новичок
делай в таблице user поле с кол-вом его голосов и делай запрос к ней. я так понимаю, что тебе нужно получить ответы на вопрос "можно или нет голосовать за статью"? то есть группировка по статьям и цепляешь кол-во голосов автора + COUNT голосов за текущую статью. потом в php при выводе статей сравниваешь числа.
голосование текущего пользователя нужно будет цеплять отдельно через LEFT JOIN по идее.
 

SaBo

Новичок
Автор оригинала: dimagolov
я так понимаю, что тебе нужно получить ответы на вопрос "можно или нет голосовать за статью"?
Вообще да, но я не уточнил такого момента, что тексты должны поступать на голосование в строгом порядке - чем раньше ты подал голос за чужой текст, тем раньше он попадёт на голосование другому пользователю.

То есть:

user1 разместил текст1.1 на голосование
user2 разместил текст2.1 на голосование
user2 проголосовал за текстN1.N1
user1 проголосовал за текстN2.N2
user1проголосовал за текстN3.N3
user2 проголосовал за текстN4.N4

Теперь если какой-то пользователь userN захочет проголосовать, то тексты попадут к нему в такой последовательности:
текст2.1
текст1.1

Если вообще смотреть ротацию текстов, то очерёдность там такая:
текст2.1
текст1.1
текст1.1
текст2.1
 
Сверху