web-dev-qa-db-fra.com

mysql interroge deux tables, la clause UNION et where

J'ai deux tables.

Je demande comme ceci:

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

J'utilise UNION parce que je veux obtenir des valeurs distinctes pour chaque utilisateur si un utilisateur existe dans le premier tableau et dans le second.

Par exemple:

table1

nameofuser
peter

table2

nameofuser
peter

si peter est sur l'une ou l'autre table, je devrais avoir le nom une fois car il existe sur les deux tables.

Pourtant, je reçois une ligne de la première table et une seconde de la table numéro deux. Qu'est-ce qui ne va pas?

Toute aide appréciée.

7
stefanosn

Il y a deux problèmes avec votre SQL:

  1. (Ceci est pas la question, mais devrait être considéré) en utilisant WHERE sur la UNION au lieu des tables, vous créez un cauchemar de performances: MySQL créera une table temporaire contenant la UNION, puis l'interrogera sur la WHERE. L'utilisation d'un calcul sur un champ (LOWER(requester_name)) aggrave encore la situation.

  2. La raison pour laquelle vous obtenez deux lignes est que UNION DISTINCT ne supprime que les doublons réels, donc le Tuple (someuser,peter) et le Tuple (someotheruser, peter) entraînent une duplication.

Modifier

Pour transformer (someuser, peter) en un duplicata de (peter, someuser), vous pouvez utiliser:

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
  ...

Donc, vous ne sélectionnez que someuser que vous connaissez déjà: peter

14
Eugen Rieck

Vous avez besoin de la clause where sur both selects:

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

Les deux requêtes étant indépendantes, vous ne devez pas essayer de les connecter autrement que par union.

2
Bohemian

Vous pouvez utiliser UNION si vous souhaitez sélectionner les lignes les unes après les autres dans plusieurs tables ou plusieurs ensembles de lignes dans une seule table, en tant que jeu de résultats unique . UNION est disponible à partir de MySQL 4.0. Cette section explique comment l’utiliser. Supposons que vous disposiez de deux tableaux répertoriant les clients potentiels et réels, le troisième répertorie les fournisseurs auprès desquels vous achetez des fournitures et que vous souhaitez créer une liste de diffusion unique en fusionnant les noms et adresses de tous. trois tables. UNION fournit un moyen de le faire. Supposons que les trois tables ont le contenu suivant:

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

1

Vous faites l'union avant et appliquez ensuite la clause where. Ainsi, vous obtiendrez une combinaison unique de "requester_name, receiver_name" et ensuite la clause where s'appliquerait. Appliquer la clause where dans chaque sélection ...

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
amit_g

Dans votre déclaration where, référencez le pseudonyme "u" pour chaque référence de champ dans votre déclaration where.

Ainsi, le début de votre déclaration where serait le suivant: where (LOWER(u.requester_name) = ... 

Ceci est similaire à la réponse que vous pouvez voir dans: Instruction WHERE après une union en SQL?

0
James Oravec