MySQL запросить две таблицы, UNION и предложение where - PullRequest
7 голосов
/ 14 марта 2012

У меня есть две таблицы.

Я спрашиваю так:

SELECT * FROM (
   Select requester_name,receiver_name from poem_authors_follow_requests  as one 
UNION 
Select requester_name,receiver_name from poem_authors_friend_requests as two 
) as u 
where (LOWER(requester_name)=LOWER('user1') or LOWER(receiver_name)=LOWER('user1'))

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

Например:

table1

nameofuser
peter

table2

nameofuser
peter

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

Тем не менее я получаю одну строку из первой таблицы, а вторую - из таблицы номер два. Что не так?

Любая помощь приветствуется.

Ответы [ 6 ]

14 голосов
/ 14 марта 2012

Есть две проблемы с вашим SQL:

  1. (это , а не вопрос, но его следует учитывать), используя WHERE вместо UNION вместо таблиц, вы создаете кошмар производительности: MySQL создаст временный таблицу, содержащую UNION, затем запросите ее по WHERE. Использование вычисления для поля (LOWER(requester_name)) делает это еще хуже.

  2. Причина, по которой вы получаете две строки, в том, что UNION DISTINCT будет подавлять только реальные дубликаты, поэтому кортеж (someuser,peter) и кортеж (someotheruser, peter) приведут к дублированию.

Редактировать

Чтобы сделать (someuser, peter) дубликатом (peter, someuser), вы можете использовать:

SELECT
  IF(requester_name='peter', receiver_name, requester_name) AS otheruser
FROM
  ...
UNION
SELECT
  IF(requester_name='peter', receiver_name, requester_name) AS otheruser
FROM
  ...

Таким образом, вы выбираете только someuser, который вы уже знаете: peter

2 голосов
/ 14 марта 2012

Вам нужно предложение where на , оба выбирает:

select requester_name, receiver_name
from poem_authors_follow_requests
where LOWER(requester_name) = LOWER('user1') or LOWER(receiver_name) = LOWER('user1')
union
select requester_name, receiver_name
from poem_authors_friend_requests
where LOWER(requester_name) = LOWER('user1') or LOWER(receiver_name) = LOWER('user1')

Два запроса не зависят друг от друга, поэтому вам не следует пытаться соединить их, кроме как с помощью union.

1 голос
/ 18 ноября 2013

Вы можете использовать UNION, если хотите выбрать строки одну за другой из нескольких таблиц или нескольких наборов строк из одной таблицы, все как один набор результатов.UNION доступен с версии MySQL 4.0.В этом разделе показано, как его использовать.Предположим, у вас есть две таблицы, в которых перечислены потенциальные и фактические клиенты, в третьей - поставщики, у которых вы покупаете расходные материалы, и вы хотите создать единый список рассылки, объединив имена и адреса из всех трех таблиц.UNION предоставляет способ сделать это.Предположим, что три таблицы имеют следующее содержание:

http://w3webtutorial.blogspot.com/2013/11/union-in-mysql.html

0 голосов
/ 08 апреля 2014

В вашем операторе where указывайте псевдоним "u" для каждого поля ссылки в вашем операторе where.

Таким образом, начало вашего оператора where будет выглядеть следующим образом: where (LOWER(u.requester_name) = ...

ThisМожно ли найти ответ, который вы можете увидеть в: выражении WHERE после UNION в SQL?

0 голосов
/ 14 марта 2012

Вы выполняете объединение до, а затем применяете предложение where.Таким образом, вы получите уникальную комбинацию «requestter_name, receive_name», а затем будет применено предложение where.Применить условие where в каждом select ...

Select requester_name,receiver_name from poem_authors_follow_requests
where (LOWER(requester_name)=LOWER('user1')
        or LOWER(receiver_name)=LOWER('user1'))
UNION 
Select requester_name,receiver_name from poem_authors_friend_requests 
where (LOWER(requester_name)=LOWER('user1')
        or LOWER(receiver_name)=LOWER('user1'))
0 голосов
/ 14 марта 2012

Вы должны иметь возможность использовать ключевое слово INTERSECT вместо выполнения вложенного запроса на UNION.

SELECT member_id, name FROM a
INTERSECT
SELECT member_id, name FROM b

можно просто переписать в

SELECT a.member_id, a.name
FROM a INNER JOIN b
USING (member_id, name)

http://www.bitbybit.dk/carsten/blog/?p=71

...