使用SQL中的UNION调用嵌套INNER JOIN - 相当丢失

时间:2011-11-23 22:33:49

标签: mysql sql join union mysql-error-1064

我有一个friends表:idfid1fid2代表两个用户之间的友谊(双向)。

users表:fidname

我想创建一个带

的函数或查询
  1. 用户ID
  2. 并返回

    1. 朋友列表(users.fid,users.name),代表所有拥有原始用户ID的朋友
    2. 我在嵌套JOIN和UNION时遇到了麻烦。我需要UNION确保我获得所有友谊(但也不要重复)。这是我到目前为止所得到的:

      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 JOIN的结果传递给UNIONs然后应用该函数。但我在这里有点迷失。有什么想法吗?

1 个答案:

答案 0 :(得分:6)

您的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

关于Joins的视觉文章

有关MySQL SELECT syntax

的信息

SELECT语法中可以看出,您将所有表连接在一起,然后应用过滤器(WHERE子句)。这会创建一个结果集。然后,您可以UNION到另一个相同格式的结果集(相同数量的列,相同的数据类型)。

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

我不确定哪个会对你有好处,可能想在现实条件下测试一下,我的三个表现相似,但我的数据很少,而且我的测试没有索引。