¿Cómo hago una combinación en SQL basado en el nombre de la tabla?

votos
0

Ok, entonces tenemos un montón de tablas que se llaman así:

training_data_001
training_data_002
training_data_003
training_data_004
training_data_005

Y luego, para encontrar aquellos en los que vemos un campo en otra tabla, simplemente llamemos master.training_type.

De todos modos, me preguntaba si alguien sabía de una forma de hacer un nombre de tabla extraño basado en unirse con este tipo de datos. Algo como esto:

SELECT foo FROM master WHERE id = ? 
INNER JOIN training_data_${master.training_type}
ON foo.id = training_data_${master.training_type}.foo_id

Sé que puedo hacer esto en el lado del cliente, pero sería bueno que el DB lo hiciera.

También tenga en cuenta: es SQL Server.

Actualización : decidí simplemente hacerlo en el lado del cliente. Gracias de todos modos a todos.

¡Gracias!

-FREW

Publicado el 09/12/2008 a las 20:54
fuente por usuario
En otros idiomas...                            


5 respuestas

votos
2

Solo puedes usar SQL dinámico para leer master.training_type para construir una cadena que luego ejecutas usando EXEC (@stringvar)

Respondida el 09/12/2008 a las 20:57
fuente por usuario

votos
1

La vista dividida es un posible enfoque. Como solo está seleccionando la columna foo, ¿realmente está comprobando la existencia de una fila en la tabla de entrenamiento a través de INNER JOIN? Además, parece que estás intentando usar foo como un alias en tu join, pero no está configurado de esa manera en tu cláusula SELECT. Como resultado, estoy adivinando aquí lo que realmente quieres.

Otra pregunta ... es el conjunto de tablas de entrenamiento estático? ¿Espera poder agregar una nueva tabla con un nuevo número de sufijo y hacer que funcione?

Otra posible solución:

SELECT
     foo
FROM
     dbo.master m
WHERE
     (training_type = '001' AND EXISTS (SELECT * FROM dbo.training_data_001 WHERE foo_id = m.id)) OR
     (training_type = '002' AND EXISTS (SELECT * FROM dbo.training_data_002 WHERE foo_id = m.id)) OR
     (training_type = '003' AND EXISTS (SELECT * FROM dbo.training_data_003 WHERE foo_id = m.id)) OR
     (training_type = '004' AND EXISTS (SELECT * FROM dbo.training_data_004 WHERE foo_id = m.id)) OR
     (training_type = '005' AND EXISTS (SELECT * FROM dbo.training_data_005 WHERE foo_id = m.id))

Si realmente desea devolver columnas de las tablas de datos de entrenamiento, entonces podría usar algo como:

SELECT
     m.id,
     COALESCE(t1.my_col, t2.my_col, t3.my_col, t4.my_col, t5.my_col) AS my_col
FROM
     dbo.master m
LEFT OUTER JOIN dbo.training_data_001 t1 ON m.training_type = '001' AND t1.foo_id = m.id
LEFT OUTER JOIN dbo.training_data_002 t1 ON m.training_type = '002' AND t2.foo_id = m.id
LEFT OUTER JOIN dbo.training_data_003 t1 ON m.training_type = '003' AND t3.foo_id = m.id
LEFT OUTER JOIN dbo.training_data_004 t1 ON m.training_type = '004' AND t4.foo_id = m.id
LEFT OUTER JOIN dbo.training_data_005 t1 ON m.training_type = '005' AND t5.foo_id = m.id
Respondida el 09/12/2008 a las 21:43
fuente por usuario

votos
1

haz algo como esto:

create view training_data_all as
select '001' as training_type, * from training_data_001
union all
select '002' as training_type, * from training_data_002
union all
select '003' as training_type, * from training_data_003
union all
select '004' as training_type, * from training_data_004
union all
select '005' as training_type, * from training_data_005

luego simplemente selecciona y únete a / desde él:

SELECT foo FROM master WHERE id = ? 
INNER JOIN training_data_all
ON foo.id = training_data_all.foo_id
WHERE training_data_all.training_type = ${master.training_type}

Si la lista de la tabla va a crecer / contraerse con el tiempo, puede escribir esta misma vista de forma dinámica en función de las tablas existentes haciendo algunas búsquedas en las tablas del sistema.

Sin embargo, nada de esto es muy eficiente. ¿Puedes simplemente ETL estos datos en una tabla combinada en un intervalo fijo?

Respondida el 09/12/2008 a las 21:22
fuente por usuario

votos
1

Si las tablas tienen la misma estructura, cree una Vista particionada en las tablas y únase a la vista. Debe hacer una restricción de verificación en una columna (tal vez una fecha) para que el optimizador de consultas pueda eliminar las particiones.

Respondida el 09/12/2008 a las 21:03
fuente por usuario

votos
1

Solo puede hacerlo con SQL dinámico en un proceso almacenado. También puede generar vistas o procesos almacenados de antemano con generación de código si no desea hacerlo sobre la marcha por razones de seguridad u otros.

Respondida el 09/12/2008 a las 20:57
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more