2009-04-20 16 views
5

Sto cercando di creare una vista che estrae i dati da due tabelle "Schedule" e "Reference".Unione di più colonne in una tabella in una singola colonna in un'altra tabella

Schedule ha 50+ colonne (è quasi completamente denormalizzato, non il mio progetto), la maggior parte delle quali contiene un valore che può essere unito a una colonna nella tabella di riferimento.

Come si scrive l'istruzione SQL per unire correttamente ciascuna colonna in Pianificazioni alla singola colonna in Riferimento?

La tabella Schedule è definita come:

CREATE TABLE [dbo].[Schedule](
    [ID] [int] NOT NULL, 
    [SCHEDULEWEEK] [datetime] NOT NULL, 
    [EMPNO] [numeric](10, 0) NOT NULL, 
    [EMPLNAME] [varchar](32) NULL, 
    [EMPFNAME] [varchar](32) NULL, 
    [EMPSENDATE] [datetime] NULL, 
    [EMPHIREDATE] [datetime] NULL, 
    [EMPTYPE] [char](1) NULL, 
    [EMPSTATUS] [char](1) NULL, 
    [SNREFUSALS] [tinyint] NULL, 
    [QUALSTRING] [varchar](128) NULL, 
    [JOBOVERSHIFTTYPE] [bit] NULL, 
    [SHORTNOTICE] [bit] NULL, 
    [SHORTNOTICEWAP] [bit] NULL, 
    [SHORTNOTICEPHONE] [varchar](32) NULL, 
    [LEADHAND] [bit] NULL, 
    [DUALCURRENCY] [bit] NULL, 
    [MIN100WINDOW] [bit] NULL, 
    [STATHOLIDAY] [bit] NULL, 
    [AREAOVERHOURS] [bit] NULL, 
    [DOUBLEINTERZONES] [bit] NULL, 
    [MAXDAYSPERWEEK] [tinyint] NULL, 
    [MAXHOURSPERWEEK] [numeric](10, 2) NULL, 
    [MAXHOURSPERSHIFT] [numeric](10, 2) NULL, 
    [MAXDOUBLESPERWEEK] [tinyint] NULL, 
    [ASSIGNEDDAYS] [tinyint] NULL, 
    [ASSIGNEDHOURS] [numeric](10, 2) NULL, 
    [ASSIGNEDDOUBLES] [tinyint] NULL, 
    [ASSIGNEDLOAHOURS] [numeric](10, 2) NULL, 
    [SHIFTNO1] [int] NULL, 
    [TEXT1_1] [varchar](64) NULL, 
    [TEXT2_1] [varchar](64) NULL, 
    [DAYFLAG1] [bit] NULL, 
    [COMMENT1] [text] NULL, 
    [SHIFTNO2] [int] NULL, 
    [TEXT1_2] [varchar](64) NULL, 
    [TEXT2_2] [varchar](64) NULL, 
    [DAYFLAG2] [bit] NULL, 
    [COMMENT2] [text] NULL, 
    [SHIFTNO3] [int] NULL, 
    [TEXT1_3] [varchar](64) NULL, 
    [TEXT2_3] [varchar](64) NULL, 
    [DAYFLAG3] [bit] NULL, 
    [COMMENT3] [text] NULL, 
    [SHIFTNO4] [int] NULL, 
    [TEXT1_4] [varchar](64) NULL, 
    [TEXT2_4] [varchar](64) NULL, 
    [DAYFLAG4] [bit] NULL, 
    [COMMENT4] [text] NULL, 
    [SHIFTNO5] [int] NULL, 
    [TEXT1_5] [varchar](64) NULL, 
    [TEXT2_5] [varchar](64) NULL, 
    [DAYFLAG5] [bit] NULL, 
    [COMMENT5] [text] NULL, 
    [SHIFTNO6] [int] NULL, 
    [TEXT1_6] [varchar](64) NULL, 
    [TEXT2_6] [varchar](64) NULL, 
    [DAYFLAG6] [bit] NULL, 
    [COMMENT6] [text] NULL 
-- Snip 
) ON [PRIMARY] 

e la tabella di riferimento è definito come:

CREATE TABLE [dbo].[Reference](
    [ID] [int] NOT NULL, 
    [CODE] [varchar](21) NOT NULL, 
    [LOCATIONCODE] [varchar](4) NOT NULL, 
    [SCHAREACODE] [varchar](16) NOT NULL, 
    [LOCATIONNAME] [varchar](32) NOT NULL, 
    [FLTAREACODE] [varchar](16) NOT NULL 
) ON [PRIMARY] 

Sto cercando di unirsi a ciascun [TEXT1_ ]/[TEXT2_] colonna Pianifica la colonna [SCHAREACODE] come riferimento. Tutta la tabella di riferimento contiene un elenco di aree in cui il dipendente potrebbe lavorare.

+0

Si prega di aggiornare la domanda con un esempio delle tabelle e quale RDBMS si sta utilizzando - ad es. MySQL, SQL Server, ecc. – Seb

+0

Ogni colonna in Schedules si unisce a una COLUMN in riferimento - o in realtà intendi per una ROW? Si prega di fornire un esempio (ad esempio 3 delle 50 colonne). –

+0

TEXTn è un elenco delimitato da virgole o solo un singolo prefisso? –

risposta

0

Da una domanda aggiornata

Forse qualcosa del genere? Sarà disordinato, non importa quello che fai.

SELECT S.ID 
    S.TEXT1_1, 
    TEXT1_1_RID = COALESCE((SELECT MAX(R.ID) FROM Reference R WHERE R.SCHAREACODE = S.TEXT1_1), 0), 
    S.TEXT1_2, 
    TEXT1_2_RID = COALESCE((SELECT MAX(R.ID) FROM Reference R WHERE R.SCHAREACODE = S.TEXT1_2), 0), 
    ... 
FROM Schedule S 
+0

Sospetto che questo potrebbe essere l'unico modo. –

6

Credo che significa unire sulla tabella di riferimento più volte:

SELECT * 
    FROM Schedule AS S 
INNER JOIN Reference AS R1 
     ON R1.ID = S.FirstID 
INNER JOIN Reference AS R2 
     ON R2.ID = S.SecondID 
INNER JOIN Reference AS R3 
     ON R3.ID = S.ThirdID 
INNER JOIN Reference AS R4 
     ON R4.ID = S.ForthID 
+0

Cosa fare se si desidera selezionare poche colonne dalla tabella di riferimento? Sarebbe come "Selezionare R1.ID, R2.ID, R3.ID, R4.ID ......." – nakul

1

La tua descrizione è un po 'carente, così ho intenzione di assumere che

Schedule ha 50+ colonne (è quasi completamente denormalizzata, non la mia progettazione), la maggior parte delle quali contiene un valore che potrebbe essere unito a una colonna nella tabella di riferimento.

significa che 1 delle 50+ colonne in Schedule è un ReferenceId. Quindi, dato un disegno tavolo come:

Schedule (MaybeReferenceId1, MaybeReferenceId2, MaybeReferenceId3, ...) 
Reference (ReferenceId) 

Qualcosa di simile:

SELECT * 
FROM Schedule 
JOIN Reference ON 
    Schedule.MaybeReferenceId1 = Reference.ReferenceId 
    OR Schedule.MaybeReferenceId2 = Reference.ReferenceId 
    OR Schedule.MaybeReferenceId3 = Reference.ReferenceId 
    OR Schedule.MaybeReferenceId4 = Reference.ReferenceId 
    ... 

avrebbe funzionato. Si potrebbe semplificare utilizzando IN se il RDBMS supporta:

SELECT * 
FROM Schedule 
JOIN Reference ON 
    Reference.ReferenceId IN (
     Schedule.MaybeReferenceId1, 
     Schedule.MaybeReferenceId2, 
     Schedule.MaybeReferenceId3, 
     Schedule.MaybeReferenceId4, 
     ... 
    ) 
0

d'accordo con TheSoftwareJedi, ma posso solo suggerire utilizzando SINISTRA join in modo che gli errori a partita non causano la riga Schedule a scomparire ?

Ovviamente, fare 28 JOINs sarà un po 'macchinoso qualunque siano i dettagli.

Non sono sicuro che mi piacerebbe chiamare questo "denormalizzato", più "abnormalized" ... :-)

+0

Suppongo che dipenda: se il tuo db si rende conto che stai partecipando allo stesso tavolo, potrebbe quindi rendersi conto che lo slurping di quella tabella in un hash in memoria è un piano ragionevole. Lo schema non è carino, ma ho visto di peggio. – araqnid

0

Prova una query come questa:

select s.*, r.schareacode from schedule s, 
where 
s.text1_1 = s.schareacode 
or s.text2_1 = s.schareacode 
or s.textx_x = s.schareacode 
.. 

si dovrebbe essere in grado di ottenere gli stessi risultati con i join tradizionali quindi ti consiglio di sperimentare anche quello.

Problemi correlati