2010-03-12 16 views
6

Tabella uno contieneSQL unire le tabelle

ID|Name 
1 Mary 
2 John 

Tabella due contiene

ID|Color 
1 Red 
2 Blue 
2 Green 
2 Black 

voglio finire con è

ID|Name|Red|Blue|Green|Black 
1 Mary Y Y 
2 John  Y  Y  Y 

Grazie per qualsiasi aiuto.


Grazie per le risposte. Ho intenzione di ripubblicare questo con alcune informazioni aggiuntive su esattamente ciò che sto cercando di fare che potrebbe complicare questo. Qualcuno può chiudere questo?

+0

Quale database? –

+0

-1: è necessario dirci quale DBMS si sta utilizzando. –

+0

Sto utilizzando ADO per connettersi a un DB Visual FoxPro. – Harley

risposta

6

Se si utilizza T-SQL è possibile utilizzare PIVOT (http://msdn.microsoft.com/en-us/library/ms177410.aspx)

Ecco interrogazione che ho usato:

declare @tbl_names table(id int, name varchar(100)) 
declare @tbl_colors table(id int, color varchar(100)) 

insert into @tbl_names 
select 1, 'Mary' 
union 
select 2, 'John' 


insert into @tbl_colors 
select 1, 'Red' 
union 
select 1, 'Blue' 
union 
select 2, 'Green' 
union 
select 2, 'Blue' 
union 
select 2, 'Black' 

select name, 
     case when [Red] is not null then 'Y' else '' end as Red, 
     case when [Blue] is not null then 'Y' else '' end as Blue, 
     case when [Green] is not null then 'Y' else '' end as Green, 
     case when [Black] is not null then 'Y' else '' end as Black 

from 
(
select n.id, name, color from @tbl_names n 
inner join @tbl_colors c on n.id = c.id 
) as subq 
pivot 
(
    min(id) 
    FOR color IN ([Red], [Blue], [Green], [Black]) 
) as pvt 

E qui viene emesso:

John  Y Y Y 
Mary Y Y  
+0

Tre problemi con questa soluzione: 1) i dati inseriti nelle tabelle non sono i dati specificati nella domanda, 2) richiede rigorosamente l'elenco di colori in fase di progettazione, il che è improbabile e 3) è un Soluzione SQL Server, non una soluzione VFP (anche se penso che l'OP abbia aggiunto solo i tag Foxpro dopo aver postato la soluzione). –

+0

Ho preso i dati dalla domanda, sembra che Harley l'abbia modificata. Lo stesso per quanto riguarda Foxpro ... –

1

si penso' Dovremo finire con qualcosa del genere:

SELECT t1.ID, 
     t1.Name, 
     CASE 
      WHEN red.ID IS NULL THEN '' 
      ELSE 'Y' 
     END As Red, 
     CASE 
      WHEN blue.ID IS NULL THEN '' 
      ELSE 'Y' 
     END As Blue 
FROM Table1 t1 
    LEFT JOIN Table2 Red 
     ON t1.ID = Red.ID AND Red.Color = 'Red' 
    LEFT JOIN Table2 Blue 
     ON t1.ID = Blue.ID AND Blue.Color = 'Blue' 

MS Sql non supporta le query PIVOT come MS Access.

+0

Solo bisogno di correggere le condizioni di join su "e Red.Color" e "e Blue.Color". – DyingCactus

+0

SQl Server 2005 e versioni successive presentano in effetti PIVOT e UNPIVOT. – DancesWithBamboo

+0

Correggere lo fa, ma si finisce comunque per digitare con forza ogni colonna/variabile su cui si desidera ruotare. MS Access ha un modo per creare dinamicamente una query pivot basata su valori. Questo è quello a cui mi riferivo dicendo "come MS Access" – Ender

-1

Contrariamente a quanto hanno detto altri manifesti; Non vedo il bisogno di un terzo tavolo. Se i colori sono una ben nota enumerazione nell'applicazione, non è necessaria una tabella "Colore".

Quello che stai cercando è un PIVOT come questo one.

2

È possibile utilizzare un'istruzione CASE con una sottoquery per immettere i valori Y.

select ID, Name, 
    case 
    when exists (select * from Colors C where C.ID = N.ID and Color = 'Red') then 
     'Y' 
    else 
     NULL 
    end 
, 
case 
    when exists (select * from Colors C where C.ID = N.ID and Color = 'Blue') then 
     'Y' 
    else 
     NULL 
    end 
, 
case 
    when exists (select * from Colors C where C.ID = N.ID and Color = 'Green') then 
     'Y' 
    else 
     NULL 
    end 
, 
case 
    when exists (select * from Colors C where C.ID = N.ID and Color = 'Black') then 
     'Y' 
    else 
     NULL 
    end 
from Names N 
+0

Penso che questa soluzione sarà molto lenta ... così tante subquery. – Ender

+0

@Ender L'uso di vincoli univoci sulla tabella Colori può aiutare a migliorare il piano di esecuzione dal momento che sarà in grado di prevedere che la sottoquery è una query scalare. O questo, il pivot o l'altro caso usato da Larry richiederebbe 4 join (o un join per ogni colore possibile). Quando si ruotano dati come questi, si finisce spesso con delle query piuttosto lente. Questo potrebbe essere evitato con un design migliore della tabella, ma sembra che il poster sia limitato a ciò che il sistema di terze parti ha già implementato. Sento che il suo dolore fa sì che sia una situazione difficile. – AaronLS

1

Come altri commentatori hanno sottolineato, non si visualizza esattamente come si collegano persone e colori. Se si sta utilizzando una tabella di collegamento (person_id, color_id), non esiste alcun modo per risolvere questo problema in SQL standard poiché richiede un pivot o una tabella incrociata, che non fa parte dello standard SQL.

Se si desidera aggiungere la condizione che il numero di colori sia limitato e noto e il tempo di progettazione, è possibile elaborare una soluzione utilizzando un join per ciascun colore e le funzioni CASE o IF in SQL. Ma non sarebbe elegante e, inoltre, non mi fiderei di quella condizione per rimanere vera a lungo.

Se riesci a trovare un modo diverso di memorizzare le informazioni sul collegamento dei colori, potresti avere più opzioni per produrre l'output desiderato, ma una diversa tecnica di memorizzazione implica un certo grado di denormalizzazione del database che potrebbe causare altre difficoltà.

In caso contrario, sarà necessario farlo in una stored procedure o codice dell'applicazione.

+0

Non c'è una tabella di collegamento, solo l'ID comune. Nella tabella due abbiamo attualmente 11 valori possibili per "colore", quindi ogni ID univoco della tabella uno potrebbe contenere fino a 11 record nella tabella due. – Harley

+0

Inoltre, la tabella uno ha 285.000 record e la tabella due ne ha 773.000, quindi la creazione di una tabella di collegamento prima dell'esecuzione di una query potrebbe non essere pratica. Poiché le tabelle vengono mantenute tramite software di terze parti, il fatto di aggiungere loro la tabella di collegamento al proprio codice probabilmente non avverrà mai. – Harley

+0

Ha più senso ora che hai aggiornato i valori ID nella tabella 2 da 1, 2, 3, 4 a 1, 2, 2, 2. Tuttavia, l'output continua a non corrispondere ai dati della tabella poiché non c'è Maria/Record blu nella tabella 2. –

Problemi correlati