Сложное состояние SQL - PullRequest
       1

Сложное состояние SQL

1 голос
/ 19 июня 2011

У меня следующая структура таблицы:

Пользователи

userID (Primary Key),
firstName,
lastName.

Sample data:
[1, John, Smith]
[2, Steve, Lan]
[3, Matt, Smith] 

Сообщение

messageID (Primary Key),
sender_userID,
receiver_userID,
messageBody,
message-visibile

message-visibile может 0 (Public) или 1 (Private)

Пример данных:

[messageID=1, sender_userID=1, receiver_userID=1, messageBody=Hello, message-visibile=1]
[2, 1, 2, Second Message, 0]
[3, 2, 1, ThirdMessage, 1]
[4, 2, receiver_userID=1, FourthMessage, 0]
[5, 3, 3, LastMessage, 0]

Теперь мне нужно отобразить все сообщения, отправленные / полученные идентификатором пользователя и его коллегами на основе значения message_visible (0/1). В приведенных выше примерах данных userID 1 является коллегой userID 2. Поэтому, если я запрашиваю userID = 1 с message_visible = 1, то я должен получить только идентификатор сообщения 1, 3. MessageID = 5 не должен появляться, потому что 3 не является коллегой никого.

Я пробовал следующий запрос, но он не возвращает ожидаемый результат:

select 
    mes.MessageId, 
    usr1.sender_userID SenderUserId, 
    usr1.firstName SenderFirstName, 
    usr1.lastName SenderLastName, 
    usr2.userID ReceiverUserId, 
    usr2.firstName ReceiverFirstName, 
    usr2.lastName ReceiverLastName, 
    mes.messageBody
from Message mes
    join Users usr1 on
        mes.sender_userID = usr1.userId
    join Users usr2 on
        mes.receiver_userID = usr2.userId
where 
    mes.sender_userID = 1 and mes.receiver_userID in (1,2) or 
    mes.receiver_userID = 1 and mes.sender_userID in (1,2)
    AND mes.message-visibile = 1

Кроме того, в другом приведенном ниже состоянии он не работает

where 
    mes.sender_userID in (1,2) or 
    mes.receiver_userID in (1,2)

Я передам набор ID коллег. Я что-то упустил?

Ответы [ 2 ]

1 голос
/ 19 июня 2011

Я думаю, вы пропускаете круглые скобки вокруг OR условие:

where 
    mes.message-visibile = 1 and
        (mes.sender_userID = 1 and mes.receiver_userID in (1,2) or 
        mes.receiver_userID = 1 and mes.sender_userID in (1,2))

-- or

where 
    mes.message-visibile = 1 and
        (mes.sender_userID in (1,2) or 
        mes.receiver_userID in (1,2))

Если условие A or B and C, оно эквивалентно A or (B and C), потому что and имеет более высокий приоритет операции.Я считаю, что вам нужно (A or B) and C.

0 голосов
/ 19 июня 2011

Ваши два состояния выглядят так:

mes.sender_userID = 1 and mes.receiver_userID in (1,2)

OR

mes.receiver_userID = 1 and mes.sender_userID in (1,2)

Со следующим ВСЕГДА true:

AND mes.message-visibile = 1

Итак, вы хотите заключить скобки в два вышеупомянутых случая. Алекс приблизился.

select 
    mes.MessageId, 
    usr1.sender_userID SenderUserId, 
    usr1.firstName SenderFirstName, 
    usr1.lastName SenderLastName, 
    usr2.userID ReceiverUserId, 
    usr2.firstName ReceiverFirstName, 
    usr2.lastName ReceiverLastName, 
    mes.messageBody
from Message mes
    join Users usr1 on
        mes.sender_userID = usr1.userId
    join Users usr2 on
        mes.receiver_userID = usr2.userId
where 
    (mes.sender_userID = 1 and mes.receiver_userID in (1,2))
    OR
    (mes.receiver_userID = 1 and mes.sender_userID in (1,2))
    AND mes.message-visibile = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...