2009-04-20 7 views
5

Je cherche à créer une vue qui extrait les données de deux tables "Schedule" et "Reference".Joindre plusieurs colonnes dans une table à une seule colonne dans une autre table

La planification comporte plus de 50 colonnes (elle est presque entièrement dénormalisée - pas ma conception), dont la plupart contient une valeur qui pourrait être jointe à une colonne dans la table de référence. Comment puis-je écrire l'instruction SQL pour joindre correctement chaque colonne dans les planifications à la colonne unique dans la référence?

Le tableau de l'annexe est définie comme suit:

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] 

Et la table de référence est définie comme:

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] 

Je suis en train de se joindre à chaque colonne [TEXT1_ ]/[TEXT2_] dans Planifiez dans la colonne [SCHAREACODE] en référence. Toute la table de référence contient une liste de zones où l'employé pourrait travailler.

+0

Veuillez mettre à jour votre question avec un exemple de vos tables et le SGBDR que vous utilisez, par exemple. MySQL, SQL Server, etc. – Seb

+0

Est-ce que toutes les colonnes des planifications se joignent à une colonne dans la référence - ou est-ce que vous voulez dire en fait une ROW? Veuillez fournir un exemple (par exemple, 3 des 50 colonnes.) –

+0

TEXTn est-il une liste délimitée par des virgules ou un seul indicatif régional? –

Répondre

0

De la question à jour

Peut-être que quelque chose comme ça? Ce sera salissant, peu importe ce que vous faites.

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

Je suppose que c'est peut-être le seul moyen. –

6

Je crois qu'il veut se joindre à la table de référence à plusieurs reprises:

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

Que se passe-t-il si je veux sélectionner quelques colonnes de la table de référence? Serait-ce comme "Sélectionnez R1.ID, R2.ID, R3.ID, R4.ID ......." – nakul

1

Votre description est un peu défaut, donc je vais supposer que

annexe a Plus de 50 colonnes (c'est presque complètement dénormalisé - pas ma conception), dont la plupart contiennent une valeur qui pourrait être jointe à une colonne dans la table de référence.

signifie que 1 des colonnes 50+ dans Schedule est un ReferenceId. Donc, étant donné une conception de table comme:

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

Quelque chose comme:

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

fonctionnerait. Vous pouvez simplifier en utilisant IN si votre SGBDR supporte:

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

D'accord avec TheSoftwareJedi, mais puis-je simplement vous suggérons d'utiliser GAUCHE JOIN afin que les échecs à correspondance ne causent pas votre ligne de l'annexe à disparaître ?

Bien sûr, faire 28 JOINs va être un peu compliqué quels que soient les détails.

Je ne suis pas sûr que j'appelle cela « dénormaliser », plus « abnormalized » ... :-)

+0

Je suppose que cela dépend: si votre DB se rend compte que vous vous joignez à la même table, il se peut alors réaliser que le fait de tailler cette table dans un hachage en mémoire est un plan raisonnable. Le schéma n'est pas joli, mais j'ai vu pire. – araqnid

0

Essayez une requête comme ceci:

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

Vous devriez être en mesure de obtenir les mêmes résultats avec les jointures traditionnelles, donc je vous recommande d'expérimenter avec ça aussi.

Questions connexes