web-dev-qa-db-fra.com

UNION MYSQL DISTINCT

J'ai deux sélections que j'exécute actuellement en tant qu'UNION avec succès.

(SELECT a.user_id,a.updatecontents as city,b.country
FROM userprofiletemp AS a
LEFT JOIN userattributes AS b ON a.user_id=b.user_id
WHERE typeofupdate='city')

UNION DISTINCT

(SELECT a.user_id,c.city,c.country
FROM userverify AS a
LEFT JOIN userlogin AS b ON a.user_id=b.user_id
LEFT JOIN userattributes AS c ON a.user_id=c.user_id
WHERE b.active=1 AND a.verifycity=0);

Les résultats reviennent comme ceci:

100 Melbourne Australia
200 NewYork America
300 Tokyo Japan
100 Sydney Australia

Le hic est que la requête apportera user_id en double (dans ce cas, le 100). Les détails de la première requête ont préséance pour moi et si l'ID utilisateur est répété dans la deuxième requête, je n'en ai pas besoin.

Existe-t-il un moyen pour qu'un UNION soit DISTINCT sur une colonne? dans ce cas, le user_id? Existe-t-il un moyen de faire l'appel ci-dessus et de ne pas obtenir les ID utilisateur en double - supprimez le second. Dois-je réécrire la requête différemment et ne pas utiliser UNION. Je le veux vraiment comme une seule requête - je peux l'utiliser pour SELECT et PHP pour éliminer les doublons si nécessaire.

thx Adam

30
Adam

Non. Vous ne pouvez pas spécifier le champ exact avec lequel vous devez vous distinguer. Cela ne fonctionne qu'avec toute la ligne.

Selon votre problème - faites simplement de votre requête une sous-requête et une externe GROUP BYuser_id

SELECT * FROM 
(SELECT a.user_id,a.updatecontents as city,b.country
FROM userprofiletemp AS a
LEFT JOIN userattributes AS b ON a.user_id=b.user_id
WHERE typeofupdate='city')

UNION DISTINCT

(SELECT a.user_id,c.city,c.country
FROM userverify AS a
LEFT JOIN userlogin AS b ON a.user_id=b.user_id
LEFT JOIN userattributes AS c ON a.user_id=c.user_id
WHERE b.active=1 AND a.verifycity=0) x
GROUP BY user_id
34
zerkms
(SELECT a.user_id,a.updatecontents as city,b.country
FROM userprofiletemp AS a
LEFT JOIN userattributes AS b ON a.user_id=b.user_id
WHERE typeofupdate='city')

UNION ALL

(SELECT a.user_id,c.city,c.country
FROM userverify AS a
LEFT JOIN userlogin AS b ON a.user_id=b.user_id
LEFT JOIN userattributes AS c ON a.user_id=c.user_id
WHERE b.active=1 AND a.verifycity=0
  AND a.user_id NOT IN
      ( SELECT user_id
        FROM userprofiletemp 
        WHERE typeofupdate='city'
      ) 
);
1
ypercubeᵀᴹ

MySQL UNION produira par défaut des lignes distinctes - cependant, la ligne entière doit être distincte. Si vous souhaitez limiter la distinction à une ou plusieurs colonnes, car d'autres colonnes ne sont pas distinctes, une méthode pour ce faire consiste à encapsuler le UNION dans une sous-requête et GROUP BY la sous-requête par les colonnes que vous souhaitez être unique.

Ici, j'encapsule l'intégralité de UNION dans une sous-requête, je lui donne un alias, puis GROUP BY la colonne unique souhaitée:

SELECT * FROM (

SELECT a.user_id,a.updatecontents as city,b.country
FROM userprofiletemp AS a
LEFT JOIN userattributes AS b ON a.user_id=b.user_id
WHERE typeofupdate='city'

UNION

SELECT a.user_id,c.city,c.country
FROM userverify AS a
LEFT JOIN userlogin AS b ON a.user_id=b.user_id
LEFT JOIN userattributes AS c ON a.user_id=c.user_id
WHERE b.active=1 AND a.verifycity=0

) aa GROUP BY user_id;

Si vous souhaitez inclure plusieurs colonnes dans la distinction, répertoriez-les après le GROUP BY: tel que GROUP BY user_id, city.


NOTE LATÉRALE: puisque, dans ce cas, UNION ne fournit pas la distinction souhaitée, il n'y a aucun avantage à simplement utiliser UNION, et apparemment "UNION ALL est beaucoup plus rapide que UNION " , vous pouvez donc utiliser UNION ALL pour accélérer cette requête.

0
bloodyKnuckles