web-dev-qa-db-ja.com

MYSQL UNION DISTINCT

現在、UNIONとして正常に実行している2つの選択があります。

(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);

結果は次のように戻ります。

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

キャッチは、クエリが重複したuser_id(この場合は100)をもたらすことです。最初のクエリの詳細は私にとって優先事項であり、user_idが2番目のクエリで繰り返される場合は必要ありません。

UNIONを列でDISTINCTにする方法はありますか?この場合、user_id?上記の呼び出しを行い、重複したuser_idを取得する方法はありますか?クエリを別の方法で書き直し、UNIONを使用しないでください。本当に1つのクエリとして必要です。必要に応じて、SELECTとPHPを使用して重複を取り除くことができます。

thxアダム

30
Adam

いいえ。区別する必要がある正確なフィールドを指定することはできません。行全体でのみ機能します。

あなたの問題のように-クエリをサブクエリにし、外側のクエリで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 はデフォルトで個別の行を生成しますが、行全体が個別である必要があります。他の列が区別されないために、区別を単一または少数の列に制限する場合、これを行う方法の1つは、サブクエリでUNIONをラップし、 GROUP BY 一意にする列によるサブクエリ。

ここでは、UNION全体をサブクエリでラップし、エイリアスを指定してから、GROUP BY希望する一意の列:

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;

区別に含めたい列が複数ある場合は、GROUP BY: といった GROUP BY user_id, city


サイドノート:この場合、UNIONは望ましい区別を提供しないため、単にUNIONを使用するだけの利点はなく、明らかに "UNION ALLUNION " よりもはるかに高速です。したがって、UNION ALLこのクエリを高速化します。

0
bloodyKnuckles