Вложение INNER JOINs с вызовами UNION в SQL - совсем потеряно - PullRequest
0 голосов
/ 24 ноября 2011

У меня есть таблица friends: id, fid1, fid2, которая представляет собой дружбу между двумя пользователями (двунаправленная).

и таблица users: fid, name

Я хотел бы сделать функцию или запрос, который принимает

  1. Идентификатор пользователя

и возвращает

  1. список друзей (users.fid, users.name), которые представляют всех друзей, которые являются друзьями с оригинальным идентификатором пользователя

У меня проблемы с вложением СОЕДИНЕНИЙ и СОЕДИНЕНИЙ.Мне нужен СОЮЗ, чтобы удостовериться, что я получаю все дружеские отношения (но также не получаю дубликаты)Это то, что у меня так далеко:

SELECT fid1 as friends FROM friendships WHERE fid2 = 123456
INNER JOIN users
ON friendships.fid1 = users.fid

UNION ALL (

SELECT fid2 as friends FROM friendships WHERE fid1 = 123456
INNER JOIN users
ON friendships.fid2 = users.fid
)

, что является ошибкой:

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INNER JOIN users ON friendships.fid1 = users.fid UNION ALL ( SELECT fid2' at line 2

в общем, у меня проблемы с командами, потому что я не понимаю, как SQLобрабатывает результаты - в обычных языках программирования я передаю результат INNER JOINs в UNION и затем применяю эту функцию.Но я немного теряюсь здесь.Есть мысли?

1 Ответ

6 голосов
/ 24 ноября 2011

Ваш WHERE должен идти после JOIN

SELECT f.fid1 AS friends
FROM friendships AS f
INNER JOIN users AS u ON f.fid1 = u.fid
WHERE f.fid2 = 123456

UNION ALL

SELECT f.fid2 AS friends
FROM friendships AS f
INNER JOIN users AS u ON f.fid2 = u.fid
WHERE f.fid1 = 123456

Визуальная статья о Объединениях

Информация о Синтаксис MySQL SELECT

Как видно из синтаксиса SELECT, вы объединяете все свои таблицы вместе, а затем применяете фильтры (предложения WHERE). Это создает один набор результатов. Затем вы можете UNION передать это другому результирующему набору того же формата (такое же количество столбцов, одинаковые типы данных).

A UNION вернет все отдельные записи, а UNION ALL вернет первый набор записей, затем второй набор записей, сохраняя порядок.

Вариант 2

SELECT CASE
          WHEN t.fid1 != 1 THEN t.fid1
          ELSE t.fid2
       END AS Friends
FROM
(
   SELECT DISTINCT f.fid1, f.fid2
   FROM friendships AS f
   LEFT JOIN users AS u ON f.fid2 = u.fid
   WHERE f.fid1 = 1 OR f.fid2 = 1
) AS t

Вариант 3

SELECT DISTINCT
   TRIM(CASE
           WHEN f.fid1 = 1 THEN ' '
           ELSE f.fid1
        END +
   CASE
      WHEN f.fid2 = 1 THEN ' '
      ELSE f.fid2
   END) AS Friends
FROM friendships AS f
LEFT JOIN users AS u ON f.fid2 = u.fid
WHERE f.fid1 = 1 OR f.fid2 = 1

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

...