0

我有以下疑问,

SELECT DISTINCT (U.uid)
FROM users U
    ,friends F
WHERE U.STATUS = '1'
    AND U.uid = F.friend_two
    AND F.friend_one = '1'
    AND F.ROLE = 'fri'

上面的查询返回 32 行。

SELECT DISTINCT (U.uid)
FROM users U
    ,friends F
WHERE U.STATUS = '1'
    AND U.uid = F.friend_one
    AND F.friend_two = '1'
    AND F.ROLE = 'fri'

上面的查询返回 15 行。

我需要合并并获取相交的结果。相交的行是 14 行(意味着两个表中相同的 U.uid 是 14 行)

4

4 回答 4

1

Another two versions worth to give them a try.
First one is using a semi join, second one joins friends table to itself.

SELECT distinct(U.uid) 
FROM users U
JOIN friends F  ON U.uid=F.friend_two AND F.friend_one='1'
WHERE U.status='1' AND F.role='fri' 
    AND EXISTS(
      SELECT 1 FROM friends F1
      WHERE U.uid=F1.friend_one 
        AND F1.friend_two='1'
        AND F1.role = 'fri'
    )
;

SELECT distinct(U.uid) 
FROM users U
JOIN friends F  ON U.uid=F.friend_two AND F.friend_one='1'
JOIN friends F1 ON U.uid=F1.friend_one AND F1.friend_two='1'
WHERE U.status='1' AND F.role='fri' AND F1.role = 'fri'
于 2013-10-27T08:55:43.317 回答
1

如果您使用EXISTS而不是连接重写 2 个查询,您可以首先删除DISTINCT(我假设这uidUsers这里的主键),其次,INTERSECTEXCEPT(也称为MINUS)操作很清楚:

查询一:

SELECT U.uid
FROM users U
WHERE U.status = '1'
  AND EXISTS
      ( SELECT *
        FROM friends F
         WHERE U.uid = F.friend_two
           AND F.friend_one = '1'
           AND F.ROLE = 'fri'
      ) ;

查询 2:

SELECT U.uid
FROM users U
WHERE U.status = '1'
  AND EXISTS
      ( SELECT *
        FROM friends F
         WHERE U.uid = F.friend_one
           AND F.friend_two = '1'
           AND F.ROLE = 'fri'
      ) ;

查询 3:INTERSECT

SELECT U.uid
FROM users U
WHERE U.status = '1'
  AND EXISTS
      ( SELECT *
        FROM friends F
         WHERE U.uid = F.friend_two
           AND F.friend_one = '1'
           AND F.ROLE = 'fri'
      )
  AND EXISTS
      ( SELECT *
        FROM friends F
         WHERE U.uid = F.friend_one
           AND F.friend_two = '1'
           AND F.ROLE = 'fri'
      ) ;

查询 4: EXCEPT( MINUS)

SELECT U.uid
FROM users U
WHERE U.status = '1'
  AND EXISTS
      ( SELECT *
        FROM friends F
         WHERE U.uid = F.friend_two
           AND F.friend_one = '1'
           AND F.ROLE = 'fri'
      )
  AND NOT EXISTS                       -- notice the NOT here
      ( SELECT *
        FROM friends F
         WHERE U.uid = F.friend_one
           AND F.friend_two = '1'
           AND F.ROLE = 'fri'
      ) ;
于 2013-10-27T08:39:01.280 回答
1

尝试这个:

SELECT *
FROM (
    SELECT DISTINCT (U.uid) UID
    FROM users U
        ,friends F
    WHERE U.STATUS = '1'
        AND U.uid = F.friend_two
        AND F.friend_one = '1'
        AND F.ROLE = 'fri'
    ) A
INNER JOIN (
    SELECT DISTINCT (U.uid) UID
    FROM users U
        ,friends F
    WHERE U.STATUS = '1'
        AND U.uid = F.friend_one
        AND F.friend_two = '1'
        AND F.ROLE = 'fri'
    ) B ON A.UID = B.UID

正如您所指定的,这基本上是您的两个查询的两个结果集的用户 ID 的交集。

于 2013-10-27T08:11:33.387 回答
1

获得交集的最直接方法是简单地加入查询:

SELECT uid FROM (
  SELECT DISTINCT U.uid
  FROM   users U JOIN friends F ON F.friend_two=U.uid AND F.friend_one = '1'
  WHERE  U.status='1' AND F.role='fri'
) NATURAL JOIN (
  SELECT DISTINCT U.uid
  FROM   users U JOIN friends F ON F.friend_one=U.uid AND F.friend_two = '1'
  WHERE  U.status='1' AND F.role='fri'
)

但是,您也可以组合查询并过滤分组结果:

SELECT   U.uid
FROM     users U JOIN friends F ON (
           F.friend_one = U.uid AND F.friend_two = '1'
         ) OR (
           F.friend_two = U.uid AND F.friend_one = '1'
         )
WHERE    U.status='1' AND F.role='fri'
GROUP BY U.uid
HAVING   SUM(F.friend_one = U.uid AND F.friend_two = '1')
     AND SUM(F.friend_two = U.uid AND F.friend_one = '1')
于 2013-10-27T08:13:38.690 回答