2010-10-31 4 views
2

Я имею дело с sql, и мой sql не так хорош, как мой ruby, поэтому я надеюсь, что вы можете мне помочь.Помогите, возможно, вложенный sql-запрос

У меня есть да таблица, которая выглядит следующим образом:

messages: 
id INTEGER PRIMARY KEY AUTO_INCREMENT 
to VARCHAR(255) 
text text 
shown DATETIME 

Пока мой сценарий генерирует эту часть в зависимости от количества игроков в онлайн.

"to = 'STEAM_0:0:xxx' OR to = 'STEAM_0:0:xxy' OR to = 'STEAM_0:0:xxz'" 

Это прослушивание активных игроков, и я хочу проверить погоду у них есть непрочитанные сообщения. Теперь с этой строки я могу сделать и Sprintf с этим:

SELECT * FROM messages WHERE shown IS NULL AND (%s)" 

и получить хороший отформатированный строку:

SELECT * FROM messages WHERE shown IS NULL AND (to = 'STEAM_0:0:xxx' OR to = 'STEAM_0:0:xxy' OR to = 'STEAM_0:0:xxz') 

Теперь у меня есть только две проблемы:

  1. SQL, возвращает более 1 записи для каждой записи поля to, я хотел бы вернуть ровно одно сообщение за каждые to (LIMIT 1 от to?), и он должен быть самым новым (сначала по id) ,

Чтобы сделать это более ясным, давайте предположим, что у меня есть таблица вроде этого:

id, to, text 
1, "x", "text1" 
2, "x", "text2" 
3, "y", "text3" 
4, "z", "text4" 
5, "y", "text5" 
6, "z", "text6" 
7, "y", "text7" 

Я хочу, чтобы получить следующее:

1, "x", "text1" 
3, "y", "text3" 
4, "z", "text4" 
  1. Я хотел бы обновить поле shown в том же SQL-вызове для NOW() для извлеченных записей.
+0

где uniqueid находится в таблице? – Dani

+0

'to' - очень плохое имя для столбца. Это зарезервированное слово в MYSQL, поэтому вам нужно будет убежать или идентифицировать его как таковое с префиксом таблицы каждый раз, когда вы ссылаетесь на него. Вероятно, вы или кто-то другой иногда забудете это сделать, а затем это вас раздражает. Может быть, что-то вроде получателя будет лучшим выбором? См. Здесь для получения более подробной информации: http://dev.mysql.com/doc/refman/5.1/en/reserved-words.html –

+0

бежать с помощью 'to', мне все равно, я хочу реальное решение, а не некоторые вопиющие о соглашениях. –

ответ

1

Edit -

Вы можете использовать этот запрос -

Select T1.[id],T1.[to],T1.[text] from Messages T1 
inner join 
    (Select [to], min([id]) as id from Messages group by [to]) T2 
on T1.[id] = T2.id 

Am предполагая новизне по идентификатору, как минимальное значение идентификатора, а сгруппированы по [к].В противном случае, вы можете использовать макс ([ID])

Это даст -

1, "x", "text1" 
3, "y", "text3" 
4, "z", "text4" 

И, вы можете использовать один и тот же запрос, чтобы получить идентификаторы, для которых [показано] столбец обновленный с текущей датой-временем -

+0

Нет, это поле 'to'. –

+0

О, хорошо .. отредактирует мой ответ в ближайшее время в соответствии с вашим обновленным вопросом. – pavanred

+0

см. Мой обновленный ответ. – pavanred

0

Что касается пункта № 1 У вас нет поля "uniqueid" в вашем столе. Я предполагаю, что вы имеете в виду «id» (ваш первичный ключ)? Если это так, вам нужно либо обновить предложение where (изменяется uniqueid на id), либо просто не делать ничего, кроме редактирования вашего сообщения, чтобы мы знали, что есть дополнительное поле.

Давайте предположим, что вы одно поле под названием «идентификатор», и что UniqueID была опечатка (также заменить% s с вашей строки)

select count(*), id 
from messages 
where shown is null and (%s) 
group by id 

даст вам количество непрочитанных сообщений для каждого идентификатора

Что касается пункта № 2: вы не можете запустить обновление и выбрать в том же запросе. Вам нужно будет сделать два отдельных вызова SQL.

update messages 
set shown = Now() 
where [some where clause here] 
+0

O право, uniqueid в моем случае, я обновлю свое сообщение –

+0

Я перепечатал сообщение, и ваше предположение было неверным. –

Смежные вопросы