Ir ao conteúdo

Problemas com select


Eder Cuer

Posts recomendados

Postado

Eae galera, estou tentando fazer um filtro, mas estou me enrolando na parte do select, vou tentar explicar.

É um sistema de transportadora, onde um usuario escolhe o estado origem, cidade origem, estado destino e cidade destino.

Meu sistema tem as seguintes tabelas:

mrh (microrregiões).

- codigo e nome da microrregião.

mrh_cidade (tabela gerada com o relacionamento de cidade com mrh).

- nessa tabela tenho o codigo da mrh e codigo da cidade.

mrh_estado (relacionamento de mrh com estado).

- nessa tabela tenho o codigo da mrh e do estado

mrh_tranportadora (relacionamento entre transportadora e mrh).

- nessa tabela tenho o codigo da mrh e da transportadora.

Na hora de fazer o select tinha que ser feito uma busca das transportadoras que atendam as cidades selecionadas.

No meu sistema eu liguei todas as cidades com as microrregiões porque na hora do cadastro o usuário escolhe quais microrregiões a transportadora atende, assim ja engloba varias cidades.

Não sei se fui claro, to tentando faz um bom tempo fazer esse select e não estou conseguindo :(

Postado

Vamos lá, não concordo com essas tabelas, mas esquece....

Descreva em forma de exercício, o que você quer que seja retornado com base em quais informações, exemplo:

Retorne as transportadoras que atendam cidades do estado de São Paulo.

Não entendi o que você quer de retorno para poder ajudar.

Postado

Eae Erciley Junior, valeu por responder...

Por exemplo, quero retorne as transportadoras que atendam a cidade de São Paulo e a cidade de Brasileia.

O usuario escolhe a cidade origem e cidade destino, ai aparece as transportadoras que atendem aquelas cidades.

Postado

Olá, a princípio acredito que seja isso, se não for, poste a estrutura de suas tabelas e qual campo as liga.

SELECT mrh_tranportadora.codigo_transportadora , transportadora.nome FROM mrh_tranportadora
INNER JOIN transportadora ON transportadora.codigo = mrh_tranportadora.codigo_transportadora
INNER JOIN mrh_cidade ON mrh_cidade.codigo_mhr = mrh_tranportadora.codigo_mhr
WHERE mrh_cidade.codigo_cidade IN(@cidade01,@cidade02)

Bom, você criou uma tabela mrh_cidade e outra mhr_estado. Não vejo sentido para essas duas tabelas. Se vai ter apenas uma microregião por estado, porque criar uma tabela com as cidades? (já que todas as cidades do estado X, faram parte da microregião Y)

Bom, acho que tem muita tabela pra pouca informação, a princípio.

Postado
Vamos lá, não concordo com essas tabelas, mas esquece....

Descreva em forma de exercício, o que você quer que seja retornado com base em quais informações, exemplo:

Retorne as transportadoras que atendam cidades do estado de São Paulo.

Não entendi o que você quer de retorno para poder ajudar.

Hehehehe... Normalmente a gente não concorda, modelar um banco de dados é realmente a grande questão em um desenvolvimento, definir corretamente as informações necessarias é um processo que normalmente é relevado no desenvolvimento.

Postado

Então Erciley, na verdade existem várias microrregiões em um estado.

Testei aqui e deu erro:

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Brasil,@Brasileia) LIMIT 0, 30' at line 4


mrh mrh_cidade mrh_transportadora
- cod_mrh - fk cod_cid - fk cod_transp
- nome - fk cod_mrh - fk cod_mrh
- fk cod_estado

Esqueci de falar que vou procurar as cidades pelos codigos, exemplo:

Quando o usuario escolhe a cidade origem/destino eu só recebo os codigos das cidades.

Postado

SET @par01:=01 //Código da cidade de São Paulo
SET @par02:=02 //Código da cidade de Brasiléia

SELECT CCC.cod_transp
,DDD.nome
FROM mrh_transportadora AS CCC
INNER JOIN transportadoras AS DDD ON DDD.codigo = CCC.cod_transp
INNER JOIN mrh_cidade AS BBB ON BBB.cod_mrh = CCC.cod_mrh
WHERE BBB.cod_cid IN (@par01,@par02)

Veja o que vai retornar, talvez precise de um Group por código da transportadora, não sei.

Poste a query que deu erro para vermos.

Postado

Bom, o comando SET, serve para declarar variáveis, do jeito que eu fiz, vai funcionar apenas se você executar em um workbench, mysql-front da vida, fiz só de exemplo, encare sendo suas variáveis.

O AAA, BBB, é um apelido que eu estou dando para as tabelas, pois em muitas consultas, que é o caso da sua, temos um campo chamado CODIGO na tabela transportadora, e temos um campo CODIGO na tabela microregiões, aí para diferenciar, damos apelidos para cada tabela

Você pode fazer assim:

select [B]transportadora[/B].codigo from [B]transportadora[/B]
inner join mkh on [B]mkh[/B].codigo = [B]transportadora[/B].codigo

ou

select [B]TAB01[/B].codigo from transportadora [B]AS TAB01[/B]
inner join mkh [B]AS TESTEEE[/B] on [B]TESTEEE[/B].codigo = [B]TAB01[/B].codigo

Postado

Entendi, seria o "Alias" ou to enganado?

Eu fiz do jeito que você me passou, não deu erro mas retornou vazio, olha:


SELECT CCC.cod_transp, DDD.nome
FROM mrh_transportadora AS CCC
INNER JOIN transportadora AS DDD ON DDD.cod_transp = CCC.cod_transp
INNER JOIN mrh_cidade AS BBB ON BBB.cod_mrh = CCC.cod_mrh
WHERE BBB.cod_cid
IN (
@13 , @14
)

Também fiz da outra maneira sem usar os apelidos e deu na mesma:


SELECT transportadora.cod_transp
,nome
FROM mrh_transportadora
INNER JOIN transportadora ON transportadora.cod_transp = mrh_transportadora.cod_transp
INNER JOIN mrh_cidade ON mrh_cidade.cod_mrh = mrh_transportadora.cod_mrh
WHERE mrh_cidade.cod_cid IN (@13,@14)

Postado

Bom, vou tentar reproduzir alguns dados aqui, se der tempo, mas.......

troque esse @13, e @14, por apenas 13 e 14

o @xxx, é uma variável, mas pelo jeito você está passando os códigos na mão, aí não precisa do @..... não sei se isso resolve, se eu criar dados aqui, aí fica mais fácil de testar e falar um select correto

Postado

Acho que deu certo, da uma olhada:


SELECT transportadora.cod_transp, nome
FROM mrh_transportadora
INNER JOIN transportadora ON transportadora.cod_transp = mrh_transportadora.cod_transp
INNER JOIN mrh_cidade ON mrh_cidade.cod_mrh = mrh_transportadora.cod_mrh
WHERE mrh_cidade.cod_cid
IN ( 13, 14 )
GROUP BY cod_transp

Postado

Então beleza, era só tirar o ARROBA mesmo.

Man, eu particularmente não concordo com tantas tabelas. Além destas tabelas, pelo jeito, você tem a tabela de estados, tabela de cidades e tabela de transportadoras, certo?

Bom, olhando bem por cima, eu reduziria essas 6 tabelas, em apenas 3, como abaixo, mas quem sou eu pra falar o que é certo ou não, mas a princípio, está parecendo que há muitas tabelas aí.

tbCD - Tabela de cidades
CDCDCD - Código cidade
CDNCEP - Cep
CDLOGR - Logradouro (Nome da rua, avenida...)
CDCIDA - Cidade
CDESTA - UF
CDBAIR - Bairro

tbTP - Tabela de transportadoras
TPCDTP - Código
TPNOME - Nome
TPCDCD - Código da cidade FK

tbMR - Tabela de microregiões
MRCDMR - Código
MRNOME - Nome
MRCDCD - Código da cidade FK
MRCDTP - Código da transportadora FK

CREATE TABLE tbCD
( CDCDCD INTEGER NOT NULL AUTO_INCREMENT
,CDNCEP INTEGER NOT NULL
,CDLOGR VARCHAR(60) NOT NULL DEFAULT ''
,CDCIDA VARCHAR(60) NOT NULL DEFAULT ''
,CDESTA VARCHAR(02) NOT NULL DEFAULT ''
,CDBAIR VARCHAR(60) NOT NULL DEFAULT ''
,PRIMARY KEY(CDCDCD)
,UNIQUE KEY(CDNCEP)
) ENGINE = INNODB

CREATE TABLE tbTP
( TPCDTP INTEGER NOT NULL AUTO_INCREMENT
,TPNOME VARCHAR(60) NOT NULL
,TPCDCD INTEGER NOT NULL
,PRIMARY KEY(TPCDTP)
,FOREIGN KEY(TPCDCD) REFERENCES tbCD(CDCDCD)
) ENGINE = INNODB;

CREATE TABLE tbMR
( MRCDMR INTEGER NOT NULL AUTO_INCREMENT
,MRNOME VARCHAR(40) NOT NULL DEFAULT ''
,MRCDCD INTEGER NOT NULL
,MRCDTP INTEGER NOT NULL
,PRIMARY KEY(MRCDMR)
,FOREIGN KEY(MRCDCD) REFERENCES tbCD(CDCDCD)
,FOREIGN KEY(MRCDTP) REFERENCES tbTP(TPCDTP)
) ENGINE = INNODB;

Digo isso mas sei que é viável esse cadastro de cidades, levando em conta que pode haver transportadoras em bairros rurais, ou em locais sem CEP, que aí não daria para relacionar, foi só um exemplo que quis dar.

Postado

Então Erciley, as tabelas são importantes mesmo.

Mas tive um problema aqui.

Da uma olhada na query:


$sql = "SELECT transportadora.cod_transp, nome
FROM mrh_transportadora
INNER JOIN transportadora ON transportadora.cod_transp = mrh_transportadora.cod_transp
INNER JOIN mrh_cidade ON mrh_cidade.cod_mrh = mrh_transportadora.cod_mrh
WHERE mrh_cidade.cod_cid
IN ( $cidorigem, $ciddestino )
GROUP BY cod_transp";

Percebi que o select não ta usando os dois codigos, exemplo:

Eu tenho que selecionar origem e destino. Vamos supor que eu seleciono 15 e 50.

Nenhuma transportadora atende a cidade 50, mas todas atendem a 15, então ele retorna todas as transportadoras mesmo assim, o certo seria selecionar apenas as transportadoras que atendem as duas cidades.

Mas se eu seleciono a cidade 15 e 33, ai me aparece só uma transportadora.

Postado

HAHAHA...

Não sei se você entendeu, mas tipo, se eu escolho 2 codigos de cidade que uma transportadora atende ai ele filtra com base nos 2 codigos, mas caso eu escolha 2 codigos e apenas 1 atenda a alguma transportadora, então ta selecionando todas as transportadoras que atendem a esse unico codigo.

Até tentei fazer mais de uma condição:


SELECT transportadora.cod_transp, nome
FROM mrh_transportadora
INNER JOIN transportadora ON transportadora.cod_transp = mrh_transportadora.cod_transp
INNER JOIN mrh_cidade ON mrh_cidade.cod_mrh = mrh_transportadora.cod_mrh
WHERE mrh_cidade.cod_cid = 15 AND mrh_cidade.cod_cid = 33
GROUP BY cod_transp

e assim:


SELECT transportadora.cod_transp, nome
FROM mrh_transportadora
INNER JOIN transportadora ON transportadora.cod_transp = mrh_transportadora.cod_transp
INNER JOIN mrh_cidade ON mrh_cidade.cod_mrh = mrh_transportadora.cod_mrh
WHERE mrh_cidade.cod_cid
IN ( 15 )
AND mrh_cidade.cod_cid
IN ( 33 )
GROUP BY cod_transp

Mas ai nem traz nenhum valor, da conjunto vazio.

Postado

*----------------------------------------

Tem como você postar alguns dados referentes essa estrutura que você falou?

       mrh                    mrh_cidade           mrh_transportadora
- cod_mrh - fk cod_cid - fk cod_transp
- nome - fk cod_mrh - fk cod_mrh
- fk cod_estado

Bom esse segundo select seu nunca irá retornar algo mesmo, pois você está falando para retornar uma cidade que o código seja igual a 15 e igual a 33

ou é um valor ou é outro ^^

Postado


[B]mrh [/B]
cod_mrh nome cod_estado
10 Brasileia 4
15 Alagonana 5


[B]mrh_cidade[/B]
cod_cid cod_mrh
13 10
14 10
18 10
32 10
33 15


[B]mrh_transportadora[/B]
cod_mrh cod_transp
10 11
11 11
12 11
13 11
14 11
10 12
11 12
12 12
13 12
14 12
10 13
11 13
12 13
13 13
14 13
10 14
11 14
10 15
11 15
15 15

Ta assim aqui.

Postado

Eae Erciley, depois de um bom tempo eu consegui fazer funcionar (com muita ajuda).

Ficou assim:


SELECT t2.cod_transp,
t2.nome
FROM (SELECT t1.cod_transp,
t1.nome
FROM transportadora t1
INNER JOIN mrh_transportadora mt1
ON mt1.cod_transp = t1.cod_transp
INNER JOIN mrh_cidade mc1
ON mc1.cod_mrh = mt1.cod_mrh
WHERE mc1.cod_cid = $Origem) t2
INNER JOIN mrh_transportadora mt2
ON mt2.cod_transp = t2.cod_transp
INNER JOIN mrh_cidade mc2
ON mc2.cod_mrh = mt2.cod_mrh
WHERE mc2.cod_cid = $Destino

valeu ae cara pela sua ajuda e paciencia. Abraço.

Postado

Que bom que conseguiu, abraço. ^^

(ehehehe, só falo para você quando tiver um tempo, ver se consegue modificar essa estrutura (se achar necessário claro), aí daria para fazer esse select mais facilmente e talvez de forma bem mais rápida para o retorno, se é que está demorando ou não (acho que não))

  • Moderador
Postado

Legal que conseguiu, só tenho uma dica que costumo usar bastante... agora que tens um select formado ee funcionando( caso nao queira mudar como sugeriu o amigo ali).. você também pode criar uma VIEW da seguinte maneira:


CREATE VIEW VWmrh AS
SELECT t2.cod_transp,
t2.nome
FROM (SELECT t1.cod_transp,
t1.nome
FROM transportadora t1
INNER JOIN mrh_transportadora mt1
ON mt1.cod_transp = t1.cod_transp
INNER JOIN mrh_cidade mc1
ON mc1.cod_mrh = mt1.cod_mrh
WHERE mc1.cod_cid = $Origem) t2
INNER JOIN mrh_transportadora mt2
ON mt2.cod_transp = t2.cod_transp
INNER JOIN mrh_cidade mc2
ON mc2.cod_mrh = mt2.cod_mrh

isto criaria uma tabela espelho baseado nesta consulta, onde todos os dados contidos.. nao poderá ser mudado nesta tabela, ou seja, se você deletar um registro das outras naqual usa na consulta, nao irá aparecer ai.

bem mas o fator que beneficia a utilizaçao é que você pode simplifica utilizando:

SELECT * FROM VWmrh WHERE mc2.cod_cid = $Destino

veja que fiz uma pquena mudançazinha onde a clausula where sai da sua anterior e entra direto na consulta depois de criada a view.

bem você pode testar isso sem interferir na sua consulta feita.. afinal você só ta criando uma tabela espelho.. se você deletar ela.. nao ira afetar nada caso nao funcione ou nao consiga fazer direito.

abraço

Postado

Então Erciley, sei que não é aconselhavel mas to meio que correndo com esse projeto, meu chefe acha que programar é fácil, e fica cobrando resultados rapidos e até fica me ameaçando de interromper o projeto, tanto que nem to me preocupando com o layout desse projeto ( complicado =/ ), mas assim que eu terminar vou revisar o trabalho todo pra melhorar algumas coisas =) .

Uma boa dica Dif, reduziria bastante o select... valeu hein.

  • Moderador
Postado

qual metodo de desenvolvimento usam na sua empresa? xp scrum? ou nem usam? me parece que você faz o serviço inteiro de uma equipe.. normalmente se tem equipe de designers, coders, analistas, programadores.. justamente pra nao sobrecarregar o tempo.

uma coisa que seu chefe ta esquecendo um dos principios básicos do desenvolvimento:

A pressa é inimiga da perfeiçao, ou seja, quanto mais ele te cobra por "agilidade" do desenvolvimento, mais a qualidade será baixa. e a repercursao disto é: clientes reclamando do sistema. isso é pessimo para sua empresa amigo. lembre-se disso. .. garanto que nem calcularam o tempo do projeto.. sem cronograma? pior de tudo trabalhar sozinho na correria? boa sorte amigo

Postado

Pois é Dif você está correto, eles mandaram uma proposta de home office, no teste eles tinham um texto falando sobre o home office e de como isso ajuda o rendimento do trabalho, eles praticamente copiaram o modo da IBM trabalhar, mas como você disse eu estou fazendo o trabalho de uma equipe inteira, e sem falar que fazia mais de 1 ano que não desenvolvia, eu tento explicar pra ele que as coisas não são tão simples, porque to tendo que fazer a analise, modelar o banco e ainda desenvolver.

E pior que eu tento colocar na cabeça dele isso, mas infelizmente ele é daqueles que só porque um sistema é fácil de usar é fácil de desenvolver também...

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!