2009-04-20 22 views
5

Ich bin auf der Suche nach einer Ansicht, die Daten aus zwei Tabellen "Schedule" und "Reference" zieht.Join mehrere Spalten in einer Tabelle zu einer einzigen Spalte in einer anderen Tabelle

Zeitplan hat 50 + Spalten (es ist fast vollständig denormalisiert - nicht mein Design), von denen die meisten einen Wert enthalten, der mit einer Spalte in der Referenztabelle verbunden werden konnte.

Wie schreibe ich die SQL-Anweisung, um jede Spalte in Schedules korrekt an die einzelne Spalte in Referenz zu verbinden?

ist der Zeitplan Tabelle wie folgt definiert:

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] 

Und die Referenztabelle ist definiert als:

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] 

ich jede [TEXT1_ ]/beitreten versuche [TEXT2_] Spalte in Planen Sie in der Spalte [SCHAREACODE] als Referenz ein. Die gesamte Referenztabelle enthält eine Liste der Bereiche, in denen der Mitarbeiter arbeiten könnte.

+0

Bitte aktualisieren Sie Ihre Frage mit einem Beispiel Ihrer Tabellen und welche RDBMS Sie verwenden - z. MySQL, SQL Server, etc. – Seb

+0

Wird jede Spalte in Schedules zu einer COLUMN als Referenz hinzugefügt - oder meinen Sie eigentlich eine ROW? Bitte geben Sie ein Beispiel an (z. B. 3 der 50 Spalten.) –

+0

Ist TEXTn eine Komma-getrennte Liste oder nur eine Ortskennzahl? –

Antwort

0

Von der aktualisierten Frage

Vielleicht so etwas? Es wird chaotisch sein, egal was du tust.

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

Ich vermute, das könnte der einzige Weg sein. –

6

Ich glaube, er bedeutet auf die Referenztabelle mehrmals zu verbinden:

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

Was ist, wenn ich einige Spalten aus der Referenztabelle auswählen möchte? Wäre es wie "Wählen Sie R1.ID, R2.ID, R3.ID, R4.ID ..." – nakul

1

Ihre Beschreibung ist ein wenig zu wünschen übrig, so dass ich gehe davon aus, dass

Zeitplan hat 50+ Spalten (es ist fast vollständig denormalisiert - nicht mein Design), von denen die meisten einen Wert enthalten, der mit einer Spalte in der Referenztabelle verknüpft werden könnte.

bedeutet, dass 1 der über 50 Spalten im Schedule eine ReferenceId ist. Also, ein Tisch-Design wie gegeben:

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

Etwas wie:

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

funktionieren würde. Man könnte es vereinfachen, indem Sie IN wenn Ihr RDBMS unterstützt:

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

Vereinbaren Sie mit TheSoftwareJedi, aber kann ich vorschlagen, nur mit LEFT JOIN, so dass Ausfälle zu Spiel nicht Ihre Schedule Reihe verschwinden lassen ?

Natürlich, 28 JOINs wird ein bisschen umständlich sein, was auch immer die Details.

Ich bin nicht sicher ich das nennen würde "denormalized", mehr "abnormalized" ... :-)

+0

Ich nehme an, es hängt davon ab: ob Ihre db erkennt, dass Sie sich der gleichen Tabelle anschließen, und erkennt dann möglicherweise, dass das Einfrieren dieser Tabelle in einen In-Memory-Hash ein vernünftiger Plan ist. Das Schema ist nicht schön, aber ich habe es schlimmer gesehen. – araqnid

0

eine Abfrage wie folgt Versuchen:

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

Sie sollten in der Lage sein Bei herkömmlichen Joins werden dieselben Ergebnisse erzielt, daher empfehle ich, dass Sie auch damit experimentieren.

Verwandte Themen