Usuário com melhor resposta
Ajuda com select - sql server 2005

Pergunta
-
Estou com uma duvida de como devo fazer um select para buscar dados a uma tabela que esta relacionada com outras duas tabelas..
Esquema base de dados:
tblArtigosBar tblequipamentos tblSaidas tblDetalheSaida
.IDartigo .IDequipamento .IDsaida .IDdetalheSaida
.Codigo .Codigo .Data .IDsaida
.Artigo .Equipamento .Valor .IDproduto
.FamiliaProduto
.Quantidade
O IDproduto sera o ID dum ArtigoBar ou dum Equipamento visto que para essa classificação eu utilizo o campo FamiliaProduto que pode ser igual a "ArtigoBar" ou "Equipamentos"
Isto esta tudo a funcionar consigo fazer o insert direitinho na tblsaidas e na detalhesSaida o meu problema é depois pra fazer o select que retorna os valores para emitir um relatorio da saida para depois imprimir... ou seja Ler a tabela DetalhesSaida e substituir esses ID's por nome a que pertencem...
Ja tive a tentar percorrer a tabela DetalheSaida a ver se conseguia fazer isso mas nao obtive os resultados certos
Espero ter explicado bem....
tks
Respostas
-
Boa Tarde,
Esse modelo de dados tem falhas graves de modelagem. Segundo as teorias relacionais, é possível sim um pai ter vários filhos e quando isso ocorre é estabelecida um relacionamento representado na figura da FK. O contrário também é possível um filho ter vários pais, mas se essa é a necessidade (e não acho que seja), a implementação está incorreta.
Da forma proposta, você não poderá traçar um relacionamento entre tblArtigosBar e tblDetalheSaida e nem entre tblDetalheSaida e tblSaidas, pois, qualquer tentativa de FK irá gerar problemas.
O mais correto seria criar uma superclasse (Produtos) e especializá-la entre Artigos e Equipamentos (subclasses). O relacionamento seria feito diretamente com Produtos e não com suas subclasses (Artigos e Equipamentos).
Em todo caso, para retornar no esquema atual, segue uma possível solução:
Code Snippet-- Recupera os artigos
SELECT
IDArtigo, Codigo, Artigo, IDSaida, Data, Valor, IDDetalheSaida, IDSaidaFROM
tblArtigosBar AS ABINNER
JOIN tblDetalheSaida AS DS AB.IDArtigo = DS.IDProdutoINNER
JOIN tblSaidas AS S ON DS.IDSaida = S.IDSaidaUNION ALL
-- Recupera os equipamentos
SELECT
IDequipamento, Codigo, Equipamento, IDSaida, Data, Valor, IDDetalheSaida, IDSaidaFROM
tblArtigosBar AS ABINNER
JOIN tblDetalheSaida AS DS AB.IDArtigo = DS.IDProdutoINNER
JOIN tblSaidas AS S ON DS.IDSaida = S.IDSaidaAgora reveja urgentemente seu modelo de dados. A dificuldade que você tem agora só tende a aumentar, pois, o problema não está na cláusula SQL, mas sim no modelo de dados. Alterações de negócio e integrações futuras podem lhe render uma verdadeira dor de cabeça.
[ ]s,
Gustavo
Todas as Respostas
-
Olá Collito,
Verifica se a sentença abaixo te ajuda a clarear as idéias!
Code Snippetselect sa.idsaida,sa.data,sa.valor,
case when ds.familiaproduto = 'Artigosbar' then ab.artigo else te.equipamento end,ds.quantidade
from tblsaida sa
join tbldetalhesaida ds on sa.id=ds.id
join tblartigosbar ab on ds.idproduto=ab.idartigo
join tblequipamentos te on ds.idproduto=te.idequipamento -
Boa Tarde,
Esse modelo de dados tem falhas graves de modelagem. Segundo as teorias relacionais, é possível sim um pai ter vários filhos e quando isso ocorre é estabelecida um relacionamento representado na figura da FK. O contrário também é possível um filho ter vários pais, mas se essa é a necessidade (e não acho que seja), a implementação está incorreta.
Da forma proposta, você não poderá traçar um relacionamento entre tblArtigosBar e tblDetalheSaida e nem entre tblDetalheSaida e tblSaidas, pois, qualquer tentativa de FK irá gerar problemas.
O mais correto seria criar uma superclasse (Produtos) e especializá-la entre Artigos e Equipamentos (subclasses). O relacionamento seria feito diretamente com Produtos e não com suas subclasses (Artigos e Equipamentos).
Em todo caso, para retornar no esquema atual, segue uma possível solução:
Code Snippet-- Recupera os artigos
SELECT
IDArtigo, Codigo, Artigo, IDSaida, Data, Valor, IDDetalheSaida, IDSaidaFROM
tblArtigosBar AS ABINNER
JOIN tblDetalheSaida AS DS AB.IDArtigo = DS.IDProdutoINNER
JOIN tblSaidas AS S ON DS.IDSaida = S.IDSaidaUNION ALL
-- Recupera os equipamentos
SELECT
IDequipamento, Codigo, Equipamento, IDSaida, Data, Valor, IDDetalheSaida, IDSaidaFROM
tblArtigosBar AS ABINNER
JOIN tblDetalheSaida AS DS AB.IDArtigo = DS.IDProdutoINNER
JOIN tblSaidas AS S ON DS.IDSaida = S.IDSaidaAgora reveja urgentemente seu modelo de dados. A dificuldade que você tem agora só tende a aumentar, pois, o problema não está na cláusula SQL, mas sim no modelo de dados. Alterações de negócio e integrações futuras podem lhe render uma verdadeira dor de cabeça.
[ ]s,
Gustavo
-
Ola Gustavo eu nao domino o relacionamento entre tabelas é uma verdade e tambem concordo plenamente que isso me tras muitos problemas mas nao estou a perceber bem como ficava o tal relacionamento que você me esta a propor... da pra exemplificar com estrutura de tabela.. ?
Como ficaria a estutura dessas tabelas entao ...
obrigado pela ajuda
-
Boa Tarde Collito,
Esse é um caso de superclasses e subclasses e existem três formas de implementação. Vou indicar a que considero mais aderente para as volatilidades que acontecem.
tblProdutos (IDProduto, <Dados comuns à todos os produtos>, Tipo)
tblArtigosBar (IDProduto, <Outros dados exclusivos de Artigo Bar>)
tblEquipamentos (IDProduto, <Outros dados exclusivos de Equipamentos>)
tblSaidas (IDSaida, Data, Valor)
tblDetalheSaida (IDDetalheSaida, IDSaida, IDProduto, Quantidade)Dessa forma os produtos são cadastrados em produtos e a saída é de produtos (independente de que produtos sejam). Caso você deseja cadastrar outros detalhes, cadastre-os conforme necessidade em tabelas auxiliares (tblArtigosBar, tblEquipamentos ou outras que por ventura vierem a surgir). Isso lhe dá muito mais autonomia e facilidade para consultar.
[ ]s,
Gustavo
-