2012-03-13 8 views
7

Ho due tabelle.mysql query due tabelle, UNION e clausola where

Mi query come questa:

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

Sto usando UNION perché voglio ottenere valori distinti per ogni utente se un utente esiste nella prima tabella e nel secondo.

Ad esempio:

table1 

nameofuser 
peter 

table2 

nameofuser 
peter 

se Peter è su entrambi i tavolo dovrei ottenere il nome di una sola volta perché esiste su entrambi i tavoli.

Ancora ottengo una riga dalla prima tabella e una seconda dalla tabella numero due. Che c'è?

Qualsiasi aiuto apprezzato.

+0

sono le colonne in entrambe le tabelle dello stesso tempo? Forse in una tabella la colonna è di tipo 'char'e nell'altra è di tipo' varchar' ci potrebbero essere degli spazi .... –

+0

nop sono entrambi lo stesso tipo di campi – stefanosn

+0

Nella tua dichiarazione where, probabilmente vuoi per fare riferimento a "u" prima di ogni campo ... così 'dove (LOWER (u.requester_name) = ...' questo è simile alla risposta che puoi vedere in: http://stackoverflow.com/questions/5452233/ where-statement-after-a-union-in-sql –

risposta

11

Ci sono due problemi con il vostro SQL:

  1. (questo è non la domanda, ma deve essere considerato) utilizzando WHERE over il UNION invece delle tabelle, si crea un incubo prestazionale: MySQL creerà una tabella temporanea contenente lo UNION, quindi la interrogherà sullo WHERE. L'utilizzo di un calcolo su un campo (LOWER(requester_name)) lo rende ancora peggiore.

  2. La ragione si ottengono due righe è, che UNION DISTINCT sarà solo sopprimere i duplicati reali, in modo che il tuple (someuser,peter) e la tupla (someotheruser, peter) si tradurrà in duplicazione.

Modifica

Per rendere (someuser, peter) un duplicato di (peter, someuser) si potrebbe usare:

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

Quindi si seleziona solo someuser che si conosce già: peter

+0

Grazie per avermi detto Eugen Rieck avevi ragione, trova duplicati come hai detto ... potresti per favore dirmi se c'è un modo per risolvere questo? (qualcuno, peter) o (peter, someuser) dovrebbe essere un duplicato nel mio caso – stefanosn

+0

Modificato la mia risposta! –

+0

Grazie mille davvero un ottimo approccio ! – stefanosn

-1

Dovresti essere in grado di utilizzare la parola chiave INTERSECT invece di eseguire una query nidificata su un UNION.

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

può semplicemente essere riscritto per

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

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

+0

MySQL non supporta la parola chiave 'INTERSECT'! – onedaywhen

2

È necessario la clausola in cui il entrambi seleziona:

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

Le due interrogazioni sono indipendenti l'uno dall'altro , quindi non dovresti provare a connetterti t orlo diverso da union.

+0

Ho provato a non funzionare ancora due volte !!! – stefanosn

0

Si sta eseguendo l'unione prima e quindi si applica la clausola where. Quindi otterresti una combinazione univoca di "requester_name, receiver_name" e quindi si applicherebbe la clausola where. Applicare la clausola where in ogni selezionare ...

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

È possibile utilizzare UNION se si desidera selezionare le file una dopo l'altra f rom diverse tabelle o diversi gruppi di righe da una singola tabella tutto come un unico set di risultati. UNION è disponibile a partire da MySQL 4.0. Questa sezione illustra come usarlo. Supponiamo di avere due tabelle che elencano i clienti potenziali e effettivi, una terza che elenca i fornitori da cui si acquistano i materiali di consumo e si desidera creare una singola mailing list unendo nomi e indirizzi di tutte e tre le tabelle. UNION fornisce un modo per farlo. Si supponga che i tre tabelle hanno i seguenti contenuti:

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

0

Nella sua dichiarazione in cui, fare riferimento l'alias "u" per ogni refence campo nella sua dichiarazione dove.

Così l'inizio della vostra dichiarazione in cui sarebbe come: where (LOWER(u.requester_name) = ...

Questo è simlar alla risposta si può vedere in: WHERE statement after a UNION in SQL?