2013-07-18 13 views
10

Ho tavolisql per unire due tabelle non correlate in un unico

table1

col1 col2  
a  b 
c  d 

e Table2

mycol1 mycol2 
e   f 
g   h 
i   j 
k   l 

voglio unire le due tabelle, che non hanno campo comune in uno tabella simile:

tabella 3

col1 col2 mycol1 mycol2 
a   b e f 
c   d g h 
null null i j 
null null k l 

ie, è come mettere i due tavoli fianco a fianco.

Sono bloccato! Per favore aiuto!

+1

quale RDBMS? chiaramente non vuoi partecipare, ma come ti aspetti di allineare le righe. perché, per esempio, e, si va con a, b? – Randy

+3

Di solito quando la domanda è qualcosa del genere, stai facendo qualcosa che in realtà non ha senso. Che uso hai per i tavoli side-by-side? Se lo stai facendo solo per visualizzare i dati nella tua applicazione, probabilmente c'è un modo migliore di quello che proponi. – catfood

+0

sqlserver. Ciao, e, f non ha bisogno di andare con a, b. Le coppie di colonne nella tabella 3 sono indipendenti l'una dall'altra. – user4109

risposta

12

Ottenere un numero di riga per ogni riga in ogni tabella, poi fare una full join usando quei numeri di riga:

WITH CTE1 AS 
(
    SELECT ROW_NUMBER() OVER(ORDER BY col1) AS ROWNUM, * FROM Table1 
), 
CTE2 AS 
(
    SELECT ROW_NUMBER() OVER (ORDER BY mycol1) AS ROWNUM, * FROM Table2 
) 
SELECT col1, col2, mycol1, mycol2 
FROM CTE1 FULL JOIN CTE2 ON CTE1.ROWNUM = CTE2.ROWNUM 

Ciò presuppone SQL Server> = 2005.

+0

buono - eccetto che è specifico RDBM - altri potrebbero usare ROWNUM – Randy

+0

@Randy: Grazie; Ho aggiunto il caveat RDBMS. – zimdanen

+0

Funziona alla grande, indipendentemente dal tavolo più lungo, grazie. Problema risolto – user4109

1

E 'davvero buono se si inserire una descrizione del motivo per cui questo problema deve essere risolto. Sto indovinando che è solo per praticare la sintassi sql?

In ogni caso, poiché le righe non hanno nulla che li collega, dobbiamo creare una connessione. Ho scelto l'ordine dei loro valori. Inoltre, dal momento che non hanno nulla che li colleghi, pone anche la domanda sul perché si vorrebbe metterli l'uno accanto all'altro in primo luogo.

Ecco la soluzione completa: http://sqlfiddle.com/#!6/67e4c/1

Il codice di selezione assomiglia a questo:

WITH rankedt1 AS 
(
    SELECT col1 
    ,col2 
    ,row_number() OVER (order by col1,col2) AS rn1 
    FROM table1 
) 
,rankedt2 AS 
(
    SELECT mycol1 
    ,mycol2 
    ,row_number() OVER (order by mycol1,mycol2) AS rn2 
    FROM table2 
) 

SELECT 
col1,col2,mycol1,mycol2 
FROM rankedt1 
FULL OUTER JOIN rankedt2 
    ON rn1=rn2 
+1

molte grazie per questo, e risposta @zimdanen, e la soluzione sqlfiddle. Blimey, eri veloce! Ho incontrato questo requisito un paio di volte .. non si tratta della sintassi sql! La destinazione finale della tabella è utilizzata da una terza parte che configura le web part sharepoint. – user4109

+0

Funziona alla grande, indipendentemente dal tavolo più lungo, grazie. Problema risolto – user4109

+0

L'ho usato quando avevo bisogno di estrarre valori di indice di identità da una tabella che corrisponde ad un'altra tabella tramite ereditarietà. non ci sono altri dati specifici che collegano i due perché la tabella più alta nella gerarchia è ereditata da molte tabelle che non sono correlate da dati specifici in ciascuna. – blindguy

2

Opzione 1: singola query

È hanno per unire le due tabelle, e se vuoi che ogni riga in table1 corrisponda a una sola riga in table2, devi avere per limitare il join così mehow. Calcola i numeri di riga in ogni tabella e unisciti a quella colonna. I numeri di riga sono specifici del database; ecco una soluzione per mysql:

SELECT 
    t1.col1, t1.col2, t2.mycol1, t2.mycol2 
FROM 
    (SELECT col1, col2, @t1_row := t1_row + 1 AS rownum FROM table1, (SELECT @t1_row := 0) AS r1) AS t1 
    LEFT JOIN 
    (SELECT mycol1, mycol2, @t2_row := t2_row + 1 AS rownum FROM table2, (SELECT @t2_row := 0) AS r2) AS t2 
    ON t1.rownum = t2.rownum; 

Ciò presuppone che la tabella1 sia più lunga di tabella2; se table2 è più lungo, utilizzare RIGHT JOIN oppure cambiare l'ordine dei sottoselezionamenti t1 e t2. Si noti inoltre che è possibile specificare separatamente l'ordine di ciascuna tabella utilizzando una clausola ORDER BY nei sottoselezionamenti.

(Vedi select increment counter in mysql)

Opzione 2: Post-processing

considerare la possibilità di due seleziona, e quindi concatenando i risultati con il linguaggio di scripting preferito. Questo è un approccio molto più ragionevole.

+1

Sono tornato a guardare le tue risposte! In realtà, non saprò se table1 è più lungo della tabella 2 o no. La domanda originale era un esempio grossolanamente semplificato del problema In realtà, ci saranno una dozzina di tabelle che devono essere combinate in un'unica vista (cioè non una tabella, ma non è importante). Le dimensioni di ciascuna dozzina di tavoli non saranno conosciute in anticipo. La terza parte ottiene la vista, quindi l'opzione 2 non è realmente fattibile. – user4109

+0

@ user4109 BTW, se non sai quale sarà più lungo, puoi fare un 'full outer join' in mysql con 'UNION' un join sinistro e un join destro. – jmilloy

Problemi correlati