2009-04-20 25 views
5

Estoy buscando crear una vista que extraiga datos de dos tablas "Programar" y "Referencia".Unir múltiples columnas en una tabla a una sola columna en otra tabla

El horario tiene más de 50 columnas (está casi completamente desnormalizado, no es mi diseño), la mayoría de las cuales contienen un valor que se puede unir a una columna en la tabla de referencia.

¿Cómo escribo la declaración de SQL para unir correctamente cada columna en Horarios a la columna única en la Referencia?

La tabla de programación se define como:

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] 

Y la tabla de referencia se define como:

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] 

Estoy tratando de unirse a cada columna [TEXT1_]/[ TEXT2_] en Programe la columna [SCHAREACODE] en la referencia. Toda la tabla de referencia contiene una lista de áreas donde el empleado podría trabajar.

+0

Actualice su pregunta con un ejemplo de sus tablas y qué RDBMS está utilizando, p. Ej. MySQL, SQL Server, etc. – Seb

+0

¿Alguna de las columnas de Schedules se une a una COLUMN de referencia, o realmente quiere decir ROW? Proporcione un ejemplo (por ejemplo, 3 de las 50 columnas). –

+0

¿Es TEXTn una lista delimitada por comas o solo un código de área único? –

Respuesta

0

De la pregunta actualizado

Tal vez algo como esto? Será desordenado sin importar lo que hagas.

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

Sospecho que esta podría ser la única forma. –

6

Creo que se refiere a unirse en la tabla de referencia varias veces:

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

¿Qué pasa si quiero seleccionar algunas columnas de la Tabla de referencia? ¿Sería como "Seleccionar R1.ID, R2.ID, R3.ID, R4.ID ......." – nakul

1

Su descripción es un poco escaso, así que voy a asumir que

Horario tiene Más de 50 columnas (está casi completamente desnormalizado, no es mi diseño), la mayoría de las cuales contienen un valor que se puede unir a una columna en la tabla de referencia.

significa que 1 de las más de 50 columnas en el Anexo es un ID de referencia. Por lo tanto, teniendo en cuenta un diseño de mesa como:

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

Algo así como:

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

funcionaría. Se podría simplificar mediante el uso de IN si su RDBMS soporta:

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

De acuerdo con TheSoftwareJedi, pero puede que acabo de sugerir el uso de LEFT JOIN de modo que las fallas-a-partido no hacen a la fila Horario a desaparecer ?

Por supuesto, hacer 28 JOINs va a ser un poco engorroso, sean cuales sean los detalles.

No estoy seguro de que me llamo a esto "desnormalizado", más "abnormalized" ... :-)

+0

Supongo que depende: si su db se da cuenta de que se está uniendo contra la misma mesa, podría darse cuenta de que sorber esa tabla en un hash en memoria es un plan razonable. El esquema no es bonito, pero he visto cosas peores. – araqnid

0

Pruebe una consulta como esta:

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

Usted debe ser capaz de Obtenga los mismos resultados con combinaciones tradicionales, así que le recomiendo que experimente con eso también.

Cuestiones relacionadas