2013-10-27 3 views
0

У меня есть следующие вопросы,Intersect или Минус в MySQL

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 рядов)

+0

Оба запроса ** идентичны **. Действительно ли они возвращают различное количество строк в каждом прогоне? – krokodilko

+2

Нет, они не являются, заменяются 'friend_one' и' friend_two'. –

ответ

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 

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

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') 
1

Если переписать 2 запроса с EXISTS вместо соединений, вы можете сначала удалить DISTINCT (я предполагаю, что uid является первичным ключом Users здесь), а затем INTERSECT и EXCEPT (также называемые MINUS) операции очевидны:

Запрос 1:

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' 
    ) ; 
1

Еще две версии стоит дать им попробовать.
Первый использует полусоединение, второй соединяет таблицу friends.

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' 
Смежные вопросы