2015-06-24 2 views
1

Я хочу написать запрос, чтобы получить все сообщения, написанные друзьями, которые у меня есть в приложении.SQL: Получить сообщения, сделанные друзьями

Моя структура таблицы:

Entity: 
--------------------- 
EntityID - PK 
FirstName - VARCHAR 
LastName - VARCHAR 

Friends: 
--------------------- 
FriendID - PK 
Friend1 - INT 
Friend2 - INT 

Post: 
--------------------- 
PostID - PK 
EntityId - INT 
Message - VARCHAR 

выше схема была упрощена для демонстрации структуры.

До сих пор я пробовал следующее, но он будет извлекать сообщения, сделанные пользователем с идентификатором 5. Как я могу сделать запрос возвратными сообщениями этого пользователя и всех его друзей?

SELECT 
    P.PostID, 
    P.Message, 
    E.FirstName, 
    E.LastName, 
FROM 
    Entity AS E 
JOIN 
    Friends AS F 
     ON (E.EntityId = F.Friend1 OR E.EntityId = F.Friend2) 
INNER JOIN 
    Posts AS P 
     ON P.EntityId = F.Friend1 OR P.Entity_Id = F.Friend2 
WHERE 
    E.EntityId = 5 
ORDER BY 
    P.PostID DESC 

Если бы я имел набор данных:

FriendId | Friend1 | Friend2 | 
    1    8    5 
    2    9    5 
    3    5    3 
    4    2    4 


PostId  | EntityId | Message 
    1    5   Hello 
    2    8   Goodbye 
    3    2   Morning 

Я бы ожидать только hello и goodbye должны быть возвращены, как идентификатор пользователя 2 не имеет никакого отношения к 5, но все 5s посты должны быть вернулся. Я смотрел на это некоторое время и, похоже, не понял этого.

+0

Вы игнорируете столбец «Отношение». Если это намеренно, опустите его из вопроса – Amit

+0

Мои приложения, да, столбец отношений отфильтровывает заблокированных пользователей. – Alex

+0

Вы нашли причину, по которой ваш запрос не работал? – Amit

ответ

2

В принципе, вам нужно только простой запрос, чтобы получить сообщения по вашим критериям:

select * from post 
where entityid in (select friend1 from friends where friend2 = 5) 
or entityid in (select friend2 from friends where friend1 =5) 
or entityid = 5; 

Затем добавьте питания нужно:

select p.postid, e.lastname,e.firstname,e.entityid , p.message from post p 
join entity e on e.entityid=p.entityid  
where p.entityid in (select friend1 from friends where friend2 = 5) 
or p.entityid in (select friend2 from friends where friend1 =5) 
or p.entityid = 5; 

А теперь изменить его к присоединиться версии:

select p.postid, e.lastname,e.firstname,e.entityid , p.message from post p 
join (
    select friend1 from friends where friend2 =5 
    union select friend2 from friends where friend1 =5 
    union select 5 from dual) m 
on p.entityid = m.friend1 
join entity e 
on p.entityid=e.entityid; 
+0

Это прекрасно работает - ударило головой о стену, чтобы переусердствовать! Благодарю. – Alex

+1

Я обычно использую IN, чтобы сделать вещи проще, прежде чем я буду оптимизировать. – Tim3880

1
SELECT 
    p.postid 
    ,p.message 
    ,e.firstname 
    ,e.lastname 
FROM posts p 
    INNER JOIN entity e 
    ON e.entityid = p.entityid 
WHERE e.entityid IN (
    SELECT friend2 
    FROM friends 
    WHERE friend1 = 5 

    UNION 

    SELECT friend1 
    FROM friends 
    WHERE friend2 = 5  
) 

возвращается:

postid message firstname lastname 
2   Goodbye John8  Doe8 

Сообщение «hello» не возвращается, поскольку его автор не является другом пользователя 5, но сам пользователь 5.

SQL Fiddle