#mysql #sql
#mysql #sql
Вопрос:
Я знаю, что этот SQL-запрос неверен, или я что-то упускаю, но у меня есть таблица, полная сообщений. Я хочу получать все сообщения, где идентификатор пользователя равен ether 1 или 2, а reply_to равен 0. Но с моим SQL-запросом он показывает ответы и теперь не отображает сообщения от пользователя 2.
Вот мой SQL
SELECT *
FROM `msg`
WHERE
`userid` LIKE '1'
OR
`user_id` LIKE '2' AND `reply_to` LIKE '0'
ORDER BY `timestamp` DESC
LIMIT 0,10;
Как бы мне исправить мой запрос, чтобы выполнить то, что я хочу?
Комментарии:
1. Используйте
=
вместоLIKE
для точных совпадений.2. Также
'1'
вместо1
, и тот факт, чтоOR
имеет меньший приоритет, чемAND
. Я отформатировал ваш запрос, чтобы показать, что он на самом деле пытается сделать.
Ответ №1:
как насчет этого?:
SELECT * FROM `msg`
WHERE `userid` in ('1','2') AND `reply_to`='0'
ORDER BY `timestamp` DESC LIMIT 0,10;
Комментарии:
1. @Jon: извините, я вас не понял. Какие кавычки?
2. Вау. Это сработало! Я приму это, когда смогу. @Harry Joy, перед вашим редактированием у вас отсутствует ‘
3. @Colum: о!! ДА. это опечатка. Пропущено
'
перед 2.
Ответ №2:
У вас есть условие, которое гласит:
user=1 or user=2 and reply_to=0
Если это оценивается как (user=1 or user=2) and reply_to=0
, то вы получите желаемый результат — неотвеченные сообщения, в которых пользователь является либо пользователем 1, либо пользователем 2. Однако, если он оценивается как user=1 or (user=2 and reply_to=0)
, вернутся все сообщения пользователя 1 и неотвеченные сообщения для пользователя 2, поэтому возникает некоторая двусмысленность.
Мой совет таков: никогда, и я имею в виду никогда, не смешивайте and
и an or
в одном и том же состоянии. Конечно, существуют правила приоритета, которые подскажут вам, что p or q and r
вычисляется тем или иным способом, но они могут отличаться на разных платформах, на разных языках, возможно, даже в разных реализациях. А представьте, если бы вместо 3 было 15 условий?
Всегда используйте круглые скобки для разделения блоков и / или. Компилятору или базе данных все равно, или они не нужны, но наши ничтожные человеческие умы работают лучше, когда мы можем представить, что на самом деле поручено делать компьютеру.
Вы могли бы переписать свой запрос следующим образом:
SELECT * FROM msg
WHERE (userid=1 OR user_id=2)
AND reply_to = 0
ORDER BY timestamp DESC
где связь между условиями более очевидна.
P.S. Избегайте использования, LIKE
если вы на самом деле не используете LIKE
подстановочные знаки.
Комментарии:
1. 1 за фактический ответ на вопрос и отсутствие альтернативного решения
Ответ №3:
ПОПРОБУЙТЕ
SELECT * FROM `msg`
WHERE `userid` IN (1,2) AND `reply_to`='0'
ORDER BY `timestamp`
DESC LIMIT 0,10;
Ответ №4:
Мне кажется, что вам нужно добавить скобки к вашему WHERE
предложению, чтобы гарантировать, что последовательность выполнения частей OR
и AND
соответствует тому, что вы хотите.
Ответ №5:
Попробуйте:
SELECT *
FROM `msg`
WHERE (`userid` = '1' OR `user_id` = '2')
AND `reply_to` = '0'
ORDER BY `timestamp` DESC LIMIT 0,10;
Скобки являются важным элементом. Вам следует использовать =
вместо Like
, когда вы не ищете подстановочные знаки.
Вы также могли бы использовать in
для user_id
проверки.
Ответ №6:
Вам нужно использовать круглые скобки (я предполагаю, что они работают в mysql так же, как и в mssql), чтобы помочь ему узнать, какие условия предложения where являются приемлемыми.
SELECT *FROM `msg`
WHERE (`userid` LIKE '1'
OR `user_id` LIKE '2')
AND `reply_to` LIKE '0'
ORDER BY `timestamp`
DESCLIMIT 0,10;
Ответ №7:
В зависимости от того, что вы на самом деле ищете в своем условном, вы либо хотите:
SELECT * FROM `msg`
WHERE (`userid` IN ('1','2'))
AND (`reply_to` = '0')
ORDER BY `timestamp` DESC
LIMIT 0, 10;
…или:
SELECT * FROM `msg`
WHERE (`userid` = '1')
OR (
(`userid` = '2')
AND (`reply_to` = '0')
)
ORDER BY `timestamp` DESC
LIMIT 0, 10;