Dúvida SQL

9 respostas
B

Olá, pessoal,

Peço ajuda pra montar uma query SQL que não estou conseguindo.

Tenho um programa pra analisar dados de uma pesquisa de mercado. Uma parte da pesquisa é sobre qual celular a pessoa possui e qual modelo ela pretende comprar em breve.

Temos as seguintes tabelas (colocarei apenas os campos relevantes):

=================
tabela: celular_fabricante
=================
celular_fabricante_ID: integer; (autoincremento, PK)
celular_fabricante_nome: varchar;

Exemplo de dados: LG, Samsung, Apple
================
tabela : celular_modelo
================
celular_modelo_ID: integer;  (autoincremento, PK)
celular_modelo_ID_fabricante: integer (FK - ligado ao PK da tabela "celular_marca")
nome_modelo: varchar;

Exemplo de dados: LG A130, Samsung J700, Iphone 4

O meu problema vem na seguinte situação: os dados de qual aparelho a pessoa tem e qual ela pretende comprar são armazenados na tabela chamada “celular_historico” que tem a seguinte estrutura:

================
tabela : celular_historico
================
ID: integer;  (autoincremento, PK)
ID_fabricante_celular_atual : integer; (FK - ligado ao PK da tabela "celular_marca")
ID_modelo_celular_atual : integer;  (FK - ligado ao PK da tabela "celular_modelo")
ID_fabricante_celular_desejado: integer; (FK - ligado ao PK da tabela "celular_marca")
ID_modelo_celular_desejado: integer; (FK - ligado ao PK da tabela "celular_modelo")

Ou seja, na tabela “celular_historico” eu encontro registros como o seguinte:

ID_________ ID_NOME_FABRICANTE____________ ID_NOME_MODELO_________ ID_NOME_FABRICANTE _DESEJADO___________ ID_NOME_MODELO_DESEJADO

1__________________ 8____________________________12__________________________ 4__________________________________________9__________________

A minha dúvida é: como consigo trazer as informações acima substituindo os ID pelos respectivos nomes? (exemplo abaixo)

ID_________ NOME_FABRICANTE____________ NOME_MODELO_________ NOME_FABRICANTE _DESEJADO___________ NOME_MODELO_DESEJADO

1_______________LG_________________________LG570____________________APPLE_________________________________Iphone 4_________

Não estou conseguindo trazer com um select com os joins convencionais pois 2 colunas são oriundas da mesma chave de uma tabela (NOME_FABRICANTE e NOME_FABRICANTE_DESEJADO) outras 2 da mesma chave de outra tabela (NOME_MODELO e NOME_MODELO_DESEJADO)

Um abraço e agradeço desde já a força

9 Respostas

pmlm

Tens de fazer dois vezes join com cada tabela, uma para o actual, outra para o desejado.

jweibe

Cara posta ai os códigos SQL de cada tabela tua…

wbdsjunior

select celular_fabricante_atual.celular_fabricante_nome celular_fabricante_nome_atual , celular_modelo_atual.nome_modelo nome_modelo_atual , celular_fabricante_desejado.celular_fabricante_nome celular_fabricante_nome_desejado , celular_modelo_desejado.nome_modelo nome_modelo_desejado from celular_historico join celular_modelo celular_modelo_atual on celular_modelo_atual.celular_modelo_ID = celular_historico.ID_modelo_celular_atual join celular_fabricante celular_fabricante_atual on celular_fabricante_atual.celular_fabricante_ID = celular_modelo_atual.celular_modelo_ID_fabricante join celular_modelo celular_modelo_desejado on celular_modelo_desejado.celular_modelo_ID = celular_historico.ID_modelo_celular_atual join celular_fabricante celular_fabricante_desejado on celular_fabricante_desejado.celular_fabricante_ID = celular_modelo_desejado.celular_modelo_ID_fabricante
você não precisa dos campos ID_fabricante_celular_atual e ID_fabricante_celular_desejado na tabela celular_historico. você consegue o fabricante pelo campo celular_modelo_ID_fabricante da tabela celular_modelo

B

Agradeço a ajuda de todos. Segue os scripts de criação das tabelas e no final alguns inserts para teste:

CREATE TABLE `celular_fabricante` (
  `celular_fabricante_ID` int(11) NOT NULL AUTO_INCREMENT,
  `celular_fabricante_nome` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`celular_fabricante_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `celular_modelo` (
  `celular_modelo_ID` int(11) NOT NULL AUTO_INCREMENT,
  `celular_modelo_id_fabricante` int(11) DEFAULT NULL,
  `nome_modelo` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`celular_modelo_ID`),
  KEY `celular_modelo_id_fabricante` (`celular_modelo_id_fabricante`),
  CONSTRAINT `celular_modelo_ibfk_1` FOREIGN KEY (`celular_modelo_id_fabricante`) REFERENCES `celular_fabricante` (`celular_fabricante_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `celular_historico` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_fabricante_celular_atual` int(11) DEFAULT NULL,
  `id_modelo_celular_atual` int(11) DEFAULT NULL,
  `id_fabricante_celular_desejado` int(11) DEFAULT NULL,
  `id_modelo_celular_desejado` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `id_fabricante_celular_atual` (`id_fabricante_celular_atual`),
  KEY `id_modelo_celular_atual` (`id_modelo_celular_atual`),
  KEY `id_fabricante_celular_desejado` (`id_fabricante_celular_desejado`),
  KEY `id_modelo_celular_desejado` (`id_modelo_celular_desejado`),
  CONSTRAINT `celular_historico_ibfk_1` FOREIGN KEY (`id_fabricante_celular_atual`) REFERENCES `celular_fabricante` (`celular_fabricante_ID`),
  CONSTRAINT `celular_historico_ibfk_2` FOREIGN KEY (`id_modelo_celular_atual`) REFERENCES `celular_modelo` (`celular_modelo_ID`),
  CONSTRAINT `celular_historico_ibfk_3` FOREIGN KEY (`id_fabricante_celular_desejado`) REFERENCES `celular_fabricante` (`celular_fabricante_ID`),
  CONSTRAINT `celular_historico_ibfk_4` FOREIGN KEY (`id_modelo_celular_desejado`) REFERENCES `celular_modelo` (`celular_modelo_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

inserts nas tabelas

INSERT INTO `celular_fabricante` VALUES (1,'LG');
INSERT INTO `celular_fabricante` VALUES (2,'APPLE');
INSERT INTO `celular_modelo` VALUES (1,1,'KP570');
INSERT INTO `celular_modelo` VALUES (2,2,'IPHONE 4');
INSERT INTO `celular_historico` VALUES (1,1,1,2,2);

Quanto a ajuda dos amigos:

pmlm: Eu estou fazendo exatamente isso: 2 joins, um pra cada parte da tabela. Isso resolve meu problema na execução do programa pois jogo metade da consulta em um dataSet e outra metade em outra Dataset, mas eu queria poder executar a query através de qualquer ferramenta de SQL sem usar esse artifício, gostaria de utilizando apenas 1 comando select.

wbdsjunior: Eu deveria mudar a estrutura da tabela “celular_historico”? Se eu remover ID_fabricante_celular_atual e ID_fabricante_celular_desejado eu não vou continuar enfrentando o mesmo problema mantendo os campos ID_modelo_celular_atual eID_modelo_celular_desejado?

I

Bootstrap ,

acho que ele quis dizer dois joins no mesmo select referenciando a mersma tabela duas vezes, exemplo:

innner join celular_fabricante  fabricante_desejado on  celular_fabricante_ID =  fabricante_desejado.ID_NOME_FABRICANTE _DESEJADO 
inner join  celular_fabricante  fabricante on celular_fabricante_ID =   fabricante .ID_NOME_FABRICANTE

dessa forma voce pode chamar o nome de um e de outro de forma independente usando o alias da tabela.

Imagino que seja essa sua dúvida.

Zeed01

Bom dia Galera,

Coloque duas vezes a tabela de historico no seu select…

± assim

Select *
from historico his_atual,
historico his_desejado,
modelo modelo_atual,
modelo modelo_desejado
where his_atual.id_modelo = modelo_atual.id_modelo and
hist_desejado.id_modelo = modelo_desejado.id_modelo

[]s

wbdsjunior

sim.

não. a tabela celular_modelo conhece o fabricante.

B

Pessoal, consegui. Agradeço a todos, especialmente Zeed01, immortalSoul e pmlm. Foi através da dica de vocês que consegui resolver.
wbdsjunior: consegui resolver o problema sem mudar a estrutura da tabela.

Segue o select que precisava, agora funcionando OK:

select a.celular_fabricante_nome, b.nome_modelo, c.celular_fabricante_nome, d.nome_modelo
from
celular_fabricante a,
celular_modelo b,
celular_fabricante c,
celular_modelo d,
celular_historico ch1
where
ch1.id_fabricante_celular_atual = a.celular_fabricante_id and
ch1.id_modelo_celular_atual = b.celular_modelo_id and
ch1.id_fabricante_celular_desejado = c.celular_fabricante_id and
ch1.id_modelo_celular_desejado = d.celular_modelo_id
wbdsjunior

[edit]não vi que você editou e tirou a segunda declaração[/edit]

e eu sugeri retirar os campos ID_fabricante_celular_atual e ID_fabricante_celular_desejado da tabela celular_historico porque você não precisa deles lá e está duplicando informação desnecessariamente.

Criado 15 de abril de 2011
Ultima resposta 15 de abr. de 2011
Respostas 9
Participantes 6