2012-01-24 4 views
6

Ho due tabelle come il seguente:limite, la scelta UNIONE duplicare il controllo colonne

parameters1

+------+-----+ 
| cod | des | 
+------+-----+ 
| 1 | aaa | 
| 2 | bbb | 
| 3 | ccc | 

parameters2

+------+-----+ 
| cod | des | 
+------+-----+ 
| 1 | mmm | 

solito aderire al set di risultati di questo due tabelle con UNION in questo modo:

SELECT cod, des 
FROM parameters1 
UNION 
SELECT cod, des 
FROM parameters2 

e ottengo questo risultato insieme:

+------+-----+ 
| cod | des | 
+------+-----+ 
| 1 | aaa | 
| 2 | bbb | 
| 3 | ccc | 
| 1 | mmm | 

voglio limitare il duplicato UNION verifica solo alla colonna cod, quindi voglio evitare che il 1 cod ottenere duplicato nel set di risultati (quando v'è un record con nome diverso e lo stesso merluzzo), voglio ottenere il nome dalla prima tabella (parameters1):

+------+-----+ 
| cod | des | 
+------+-----+ 
| 1 | aaa | 
| 2 | bbb | 
| 3 | ccc | 

AGGIORNAMENTO Se rimuovo il record 1 dal parameters1 tavolo (DELETE FROM parameters1 WHERE cod = 1) dovrei ottenere questo risultato insieme:

+------+-----+ 
| cod | des | 
+------+-----+ 
| 1 | mmm | ---> FROM parameters2 
| 2 | bbb | 
| 3 | ccc | 

E 'possibile limitare il controllo duplicato di un'Unione a un solo campo o alcuni campi? Come ?

La soluzione dovrebbe funzionare su un ambiente multidatabase (MSSQL, PostgreSQL, MySQL).

+0

possibile duplicato del [dell'Unione distinta di SQL Server per una colonna] (http://stackoverflow.com/questions/7338884/sql-server-distinct-union-for-one-column) – ruakh

+0

Si prega di spiegare la logica del perché la riga '(1, 'aaa')' viene scelta sopra la riga '(1, 'mmm')' eg perché ''aaa' <'mmm'', forse? La risposta accettata sembra scegliere una riga arbitraria. – onedaywhen

+0

È una logica che ho definito perché una tabella ha la precedenza ... – aleroot

risposta

9
SELECT cod, des 
FROM parameters1 p1 
UNION ALL 
SELECT cod, des 
FROM parameters2 p2 
WHERE NOT EXISTS (
    SELECT 1 
    FROM parameters1 p1sub 
    WHERE p1sub.cod = p2.cod 
) 
+0

Soluzione fantastica, grazie! – aleroot

+2

È corretto ma dovrebbe essere più veloce con 'UNION ALL'. –

+0

@ypercube Ottimo punto, non serve cercare di filtrare i duplicati qui ... aggiornati. –

2

La soluzione in this link deve essere adattabile a tali ambienti, in quanto è SQL standard (è possibile utilizzare ISNULL se non è disponibile). Non sono sicuro di quale sia la disponibilità di FULL OUTER JOIN, ma dovrebbe essere disponibile anche su tutte e tre le piattaforme.

Nel tuo caso, la soluzione finirà per assomigliare:

SELECT p1.cod, ISNULL(p1.des, p2.des) AS des 
FROM parameters1 p1 
    FULL OUTER JOIN parameters2 p2 ON p1.cod = p2.cod 

... ma ... MySQL a quanto pare non supporta FULL OUTER JOIN, in modo da poter utilizzare un altro trucco in questo caso:

SELECT p1.cod, ISNULL(p1.des, p2.des) AS des 
FROM parameters1 p1 
    LEFT JOIN parameters2 p2 ON p1.cod = p2.cod 
UNION ALL 
SELECT p2.cod, p2.des 
FROM parameters2 p2 
    LEFT JOIN parameters1 p1 ON p1.cod = p2.cod 
WHERE p1.cod IS NULL 
+0

la soluzione non copre i casi in cui un parametro risiede solo nella seconda tabella, cioè il risultato sarà sempre lo stesso di una semplice selezione dalla prima tabella – newtover

+0

Buon punto.Un FULL OUTER JOIN dovrebbe aggiustarlo. – mwigdahl

+0

Non funziona perché se rimuovo il record dai parametri 1 non ottengo nulla ... Vedi la domanda aggiornata, e mi dispiace per non essere molto preciso nella domanda. – aleroot

0

Modifica seconda query unione per ottenere solo parametri2 dove parameters2.id non è in parametri1.