2008-12-09 9 views
0

Ok, donc nous avons un tas de tables qui sont nommés comme ceci:Comment faire une jointure en SQL en fonction du nom de la table?

training_data_001 
training_data_002 
training_data_003 
training_data_004 
training_data_005 

Et puis pour trouver ceux que nous regardons un champ dans une autre table, nous allons simplement appeler master.training_type.

Quoi qu'il en soit, je me demandais si quelqu'un connaissait un moyen de faire un nom de table bizarre en se fondant sur ce type de données. Quelque chose comme ceci:

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

Je sais que je peux le faire sur le côté client, mais il serait agréable d'avoir la db faire.

Notez également: c'est SQL Server.

Mise à jour: J'ai décidé de le faire du côté client. Merci quand même tout le monde.

Merci!

-fREW

+0

La clause WHERE vient après tous vos JOIN –

Répondre

2

Vous ne pouvez utiliser SQL dynamique pour lire master.training_type pour construire une chaîne que vous exécutez puis en utilisant EXEC (@stringvar)

1

Vous ne pouvez le faire avec SQL dynamique dans une procédure stockée. Vous pouvez également générer des vues ou des processus stockés à l'avance avec la génération de code si vous ne voulez pas le faire à la volée pour des raisons de sécurité ou autres.

1

Si les tables ont toutes la même structure, créez un Partitioned View entre les tables et rejoignez la vue. Vous devez effectuer une contrainte de vérification sur une colonne (peut-être une date) afin que l'optimiseur de requête puisse effectuer l'élimination de la partition.

1

faire quelque chose comme ceci:

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 

puis il suffit de sélectionner et rejoindre à/de celui-ci:

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 liste des tables est de faire croître/rétrécir au fil du temps, vous pouvez écrire ce même Vue dynamique basée sur les tables existantes en effectuant des recherches dans les tables système.

Rien de tout cela n'est très efficace. Pouvez-vous juste ETL ces données dans une table combinée à un certain intervalle fixe?

1

La vue partitionnée est une approche possible. Puisque vous ne sélectionnez que la colonne foo, vérifiez-vous simplement l'existence d'une ligne dans le tableau d'entraînement via INNER JOIN? En outre, il semble que vous essayez d'utiliser foo comme un alias dans votre jointure, mais il n'est pas configuré de cette façon dans votre clause SELECT. En conséquence, je devine ici ce que vous voulez vraiment.

Une autre question ... est l'ensemble des tables de formation statiques? Est-ce que vous vous attendez à pouvoir ajouter une nouvelle table avec un nouveau numéro de suffixe et le faire fonctionner?

Une autre solution possible:

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 vous voulez vraiment retourner les colonnes des tables de données de formation, vous pouvez ensuite utiliser quelque chose comme:

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 
Questions connexes