Como eu faço uma junção em SQL com base no nome da tabela?

votos
0

Ok, por isso temos um monte de tabelas que são chamados assim:

training_data_001
training_data_002
training_data_003
training_data_004
training_data_005

E, em seguida, para encontrar aqueles olhamos para um campo em outra tabela, vamos chamá-lo master.training_type.

Enfim, eu queria saber se alguém sabia de uma maneira de fazer um nome de tabela estranho baseado juntar-se com este tipo de dados. Algo assim:

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

Eu sei que eu posso fazer isso no lado do cliente, mas seria bom ter a db fazê-lo.

Além disso, note: é SQL Server.

Atualização : Eu decidi fazê-lo apenas no lado do cliente. Obrigado de qualquer forma todos.

Obrigado!

-fREW

Publicado 09/12/2008 em 20:54
fonte usuário
Em outras línguas...                            


5 respostas

votos
2

Você só pode usar SQL dinâmico para ler master.training_type para construir uma cadeia de caracteres que você, em seguida, executar usando EXEC (@stringvar)

Respondeu 09/12/2008 em 20:57
fonte usuário

votos
1

A vista é particionado uma abordagem possível. Desde que você está selecionando apenas a coluna foo, você está realmente apenas a verificação de existência de uma linha na tabela de formação através do INNER JOIN? Além disso, parece que você está tentando usar foo como um alias em sua juntar-se, mas não está configurado dessa forma em sua cláusula SELECT. Como resultado, eu estou supondo aqui sobre o que você realmente quer.

Outra questão ... é o conjunto de tabelas de treinamento estático? Você está esperando para ser capaz de adicionar uma nova tabela com um novo número de sufixo e tê-lo apenas trabalhar?

Outra solução possível:

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

Se você realmente quer retornar colunas das tabelas de dados de treino, então você poderia 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
Respondeu 09/12/2008 em 21:43
fonte usuário

votos
1

fazer algo como isto:

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

em seguida, basta selecionar e juntar-se de / para ele:

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}

Se a lista de tabela é crescer / diminuir ao longo do tempo, você pode escrever essa mesma visão dinamicamente com base nas tabelas que existe, fazendo algumas pesquisas para as tabelas do sistema.

Nada disso é muito eficiente embora. Você pode apenas ETL esses dados em uma tabela combinada em algum intervalo fixo?

Respondeu 09/12/2008 em 21:22
fonte usuário

votos
1

Se as tabelas são todos a mesma estrutura, criar um modo de exibição particionado através das tabelas e junte-se contra a visão. Você precisa fazer uma restrição de verificação sobre uma coluna (talvez uma data) para que o otimizador de consulta pode fazer eliminação de partição.

Respondeu 09/12/2008 em 21:03
fonte usuário

votos
1

Você só pode fazê-lo com SQL dinâmico em uma proc armazenado. Você também pode gerar pontos de vista ou procedimentos armazenados de antecedência com a geração de código, se você não quiser fazê-lo em tempo real para a segurança ou outros motivos.

Respondeu 09/12/2008 em 20:57
fonte usuário

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