Jump to content
  • 0
Didyo

LEFT JOIN com operador IN (1,2,4,5,7)

Question

Olá pessoal, não sei se é possível mas minha ideia seria usar o operador IN dentro de um JOIN 
substituindo o "=".
Ex: Teria uma tabela itens_cardapio (car_id, car_nome, car_bebidas)
e outra tabela > bebidas (b_id, b_nome)

Sei que poderia relaciona n:m tendo uma tabela tipo itens_cardapio_has_bebidas (fk_car_id, fk_b_id) porém queria fazer diferente pois para o que quero isso geraria muitas linhas na tabela de junção.

Gostaria que o campo car_bebidas na 1ª tabela armazenasse os ids das bebidas da 2ª tabela. Ex. car_bebidas=1,2,5,6,9,11
e na consulta ficaria algo do tipo:
SELECT i.* , GROUP_CONCAT(b.b_nome) FROM itens_cardapio i 
INNER JOIN bebidas b ON (b.b_id IN i.car_bebidas)

Tentei também algo tipo 

SELECT i.* , (SELECT b.nome FROM bebidas b WHERE b.b_id IN i.car_bebidas) FROM itens_cardapio i 

Usei algumas variação com GROUP BY e GROUP_CONCAT,...

Consegui obter resultados como:
- a primeira bebida de cada item do cardápio
- repetir várias vezes cada bebida por item,
e outros, mas nenhum 100% correto.

Se no IN usar os números dos ids das bebidas manualmente, ao invés de puxar de um campo, ele busca as bebidas pedidas,
porém não fica dinâmico, pois é sempre os mesmos números de modo a todos itens do cardápio ficaram com (coca-cola,sprite,fanta) por exemplo.

Se tiverem alguma ideia agradeço.

  • +1 1

Share this post


Link to post
Share on other sites

3 answers to this question

Recommended Posts

  • 0

Olá pessoal, consegui solucionar o problema de 2 formas.

Minha ideia era relacionar 2 tabelas de um cardápio, exemplo (itens e bebidas) sem usar relacionamento n:m, mas armazenando os ids das bebidas em um campo "lista_bebidas".

 

Para quem desejar,  ao invés de usar o operador IN no JOIN ON,
basta usar o FIND_IN_SET com GROUP_CONCAT e GROUP BY
para agrupar os resultados por linha.

 

Tabela cardapio_itens (* apenas demonstrativo)

id  ||    item_nome    ||   lista_bebidas 

1   ||     refri 300ml    ||  1,2,4,5

2   ||     refri 600ml    ||  2,3,5

 

Tabela cardapio_bebidas (* apenas demonstrativo)

 id ||    nome_bebida  

1   ||   cola

2   ||   guaraná

3   ||   uva

4   ||   laranja

5   ||   limão

 

Solução 1 - com uso de JOIN: (minha preferida)

SELECT i.*, GROUP_CONCAT(b.nome_bebida) as bebidas FROM cardapio_itens i 

LEFT JOIN cardapio_bebidas b ON FIND_IN_SET(b.id, i.lista_bebidas) 

GROUP BY i.id       

 

Resultado:

1   ||    refri 300ml    ||     cola, guaraná, laranja, limão

2   ||    refri 600ml    ||     guaraná, uva, limão  

 

Solução 2 - com uso de Subquery: 

SELECT i.*, (SELECT GROUP_CONCAT(b.nome_bebida) as bebidas FROM cardapio_bebidas b WHERE  FIND_IN_SET(b.id, i.lista_bebidas)  ORDER BY b.nome_bebida ASC)   FROM cardapio_itens i 

 

Essa escolha foi para evitar um grande número de linhas em uma tabela de ligação n:m, devido a serem vários restaurantes e bares com várias bebidas em tamanhos diferentes.

Sei que para uma questão de integridade,... a melhor opção seria a terceira tabela n:m. Se o esperado fosse apenas alguns milhares de linhas até usaria n:m com uma tabela de junção itens_has_bebidas.

 

Obrigado a todos

Share this post


Link to post
Share on other sites
  • 0

 

lista_bebidas  passou a ser uma chave estrangeira?

 

Se você deletar um item como limão por exemplo isso seria fácil de atualizar em todos os registros de refri na tabela cardapio_itens ?

 

 

Share this post


Link to post
Share on other sites
  • 0
4 horas atrás, Bergs disse:

 

lista_bebidas  passou a ser uma chave estrangeira?

 

Se você deletar um item como limão por exemplo isso seria fácil de atualizar em todos os registros de refri na tabela cardapio_itens ?

 

 

Olá Bergs, nesse caso específico não usei como chave estrangeira. A necessidade e objetivo são outros.
Sei que se usa-se n:m seria mais prático e fácil de garantir a integridade.  

 

No exemplo que usei, é claro que se limão tiver escrito errado (lemãoo) na tabela cardapio_bebidas e for corrigido (UPDATE),
automaticamente a correção afetará todas as linhas que tenham limão em cardapio_itens.
pois nessa tabela, embora em um único campo, estão armazenados apenas os IDs das bebidas.

 

Também seria importante cuidar para não permitir que limão seja removido da tabela cardapio_bebidas 
caso esteja em alguma linha em cardapio_itens.

Poderia usar uma TRIGGER com uma validação antes de a linha ser removida (BEFORE DELETE).

Use um campo (quantidade) para controlar quantos itens usam a bebida limão e só permita que seja removida caso a quantidade seja 0;

 

Se desejar que quando nenhum cliente possuir mais a bebida limão,
a mesma seja removida da lista em cardapio_bebidas
poderia usar um campo quantidade (qnt) na tabela cardapio_bebidas
e usar UPDATE quando a bebida é inserida ou removida em cardapio_itens.

Depois, se a quantidade for 0, você pode remover a bebida da lista.


Para otimizar esses processos poderia usar TRIGGER no UPDATE da tabela cardapio_bebidas, 
onde, quando qnt=0 , DELETE. 

 

Na situação que estou usando, em (cardapio_bebidas) um usuário não poderá excluir uma bebida (exemplo: limão),

pois a mesma poderá estar sendo usada por outros restaurantes e bares.

Esta tabela apenas armazena todas opções disponíveis de bebidas

sendo que o usuário pode apenas incluir novas bebidas, sendo que cada bebida é única UNIQUE.

 

No entanto o usuário pode remover a bebida limão de sua lista de bebidas (cola, limão, laranja)  que está armazenada apenas os ids (1,3,4) das mesmas em um campo na tabela cardapio_itens.  Mas lembrando, limão não será removido da tabela cardapio_bebidas pois outros usuários poderão ter essa bebida.

 

No meu caso não deverá haver a necessidade de excluir uma bebida se a quantidade for 0,
apenas se ela não existir ou se o nome estiver escrito errado. 

 

Isso porque serão armazenadas as principais marcas com suas variações (coca-cola, pepsi, coca-cola zero,...)  em torno de 40 no máximo 60 registros 
e no caso das demais marcas serão armazenadas apenas os sabores (limão, guaraná, limão zero, laranja,...) em torno de mais uns 50 registros. Total uns 100 registros apenas. 

 

Mesmo se colocar todos refrigerantes com marca e sabor  seria no máximo 300 a 400 registros. 

Vamos supor que dê 5 ou 10 Mil registros incluindo cervejas, vinhos, espumantes,...  
Não acredito que manter tais registro apenas para consulta irá prejudicar muito o banco de dados pois usam indÍces (PRIMARI KEY).

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • By patrickjnunes1995
      Bom dia, estou tendo dificuldades em recuperar dados de uma tabela do banco de dados, pelo PHP.
      <?php require_once('conexao_bd.php'); $consulta = "SELECT * FROM table"; $con = $mysqli->query($consulta) or die ($mysql->error); echo $dado["nome"]; ?>  
      E o arquivo conexão_bd.php está ok.
       
      Não pude encontrar em nenhuma página pela internet essa solução.
       
      Quero que exiba na página PHP, valores como algum nome, gravado na tabela do banco de dados.
       
      Desde já obrigado.
    • By srs1999_
      Tópico
       
      Site em Código
      Sobre desenvolver sites sem o wordpress que ja tá tudo ali feito que seja um site dinâmico ou seja com banco de dados , APIs de pagamento, Painel para o usuário ,  além de todas  as funções que tem no wordpress e você teria propriedade pra explicar sobre detalhes mais técnicos da produção onde no wordpress só quem entende de progrqmação explicaria algum detalhe técnico 
      Então usando basicamente : 
      FRONT END 
      HTML 
       CSS 
      JAVASCRIPT 
      ALGUMA DE BACKEND COMO PHP E BANCO DE DADOS
      Pode se criar sites/sistemas tão bons ou melhores que no wordpress
       
      Fato : o proprio wordpress é feito em php e ate o proprio facebook tbm em php
      Fato 2 :  cerca de 70% dos sites são feitos em Wordpress
       
      Acho esse lance de procurar o caminho mais fácil limita muito a pessoa por exemplo é facil editar imagens no paint bem intuitivo , agora para editar no photoshop com muitas outras possibilidades  acaba sendo importante ir explorando essa elaboração mais difícil  com um mesmo objetivo. No caso do exemplo ( editar imagens )  
       
      Reflexão:
      Vale a pena se dedicar a trabalhar com a ferramenta Wordpress apenas por ser um meio rápido de ganhar dinheiro ?
      Ou trabalhar sem wordpress  usando tudo que exigido pra criar coisas originais mais que não seria tão rápido a produção. Mas creio que além dos sites feitos também geraria a possibildade de vender o sistema web criado para o cliente personalizar .
       
      Você Desenvolveria de que forma :
       Wordpress apenas ?
       
      Conhecer programação pra trabalhar 
      com  Wordpress ?
       
      Produzir tudo só com programação totalmente dinâmico sem  Wordpress?
    • By Duilio Gomes Pereira
      Tenho um banco de dados com mais de 21 mil usuários do wordpress. Como faço para deletar os usuário no  Phpmyadmin e deixar apenas 2 usuários?
       
      Pois só preciso de 2 usuários neste site.
       
      Obrigado!
    • By Duilio Gomes Pereira
      Olá!
      Tenho um bando de dados com mais de 21 mil usuários do wordpress. Como faço para deletar no Phpmyadmin e deixar apenas 2 usuários?
      Obrigado!
    • By Junior SAIZO
      Estou com uma duvida na qual não obtive solução. Tenho um objeto Array values e um array status, onde eu quero relacionar os índices do objeto Array values aos indices do array status. De modo que eu possa escrever um teste lógico onde: Se o indice 0 do objeto Array values for diferente de null (ou seja, contém valor), então o indice 0 do array status receberá o valor '1'.
      OU 
      Se o indice 1 do objeto Array values for diferente de null (ou seja, contém valor), então o indice 1 do array status receberá o valor 1.
       
      Por exemplo, antes do teste lógico:
      values:[ 0 => [ 0 => "1,02" 1 => "2,032" 2 => "32,01" 3 => "0,021" ] 1 => [ 0 => "null" 1 => "null" 2 => "8,258" 3 => "1,021" ] 2 => [ 0 => "4,021" 1 => "6,258" 2 => "null" 3 => "10" ] ] status:[ 0 => "0" 1 => "0" 2 => "0" ] Após o teste lógico:
       
      status:[   0 => "1"   1 => "0"   2 => "0" ] Neste exemplo só o indice 0 do array status recebeu o valor "1", porque APENAS o array 0 do objeto Array values tinha valores diferente de null.
       
      ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
       
      O array status sempre terá o mesmo número de índices que o objeto Array values terá de arrays (Se array status tem 5 indices (0, 1, 2, 3, 4), o objeto Array value terá 5 arrays (0, 1, 2, 3, 4)). Além disso o array status sempre iniciará com os valores do indice igual a '0'. E se os valores dos indices do objeto values forem TODOS diferentes de null, cada indice do array status receberá o valor '1'.
       
      Exemplificando:

       
      <?php status:[   0 => "1",   1 => "1",   2 => "1", ] ?>  
       
      Em outro fórum obtive a seguinte resposta:
       
      <?php $aValues = [ 0 => [ 0 => "1,023" , 1 => "0,023" , 2 => "5,023" , 3 => "1" ], 1 => [ 0 => null , 1 => null , 2 => "5" , 3 => "1,87" ], 2 => [ 0 => "null" , 1 => null , 2 => null , 3 => null ] ]; $aStatus = [ 0 => 0 , 1 => 0 , 2 => 0 ]; foreach ($aValues as $chave => $values) { $status = 1; foreach ($values as $value) { // se tiver qquer valor null status recebe 0 if ($value == null) { $status = 0; break; } } $aStatus[$chave] = $status; } echo '<pre>'; print_r($aStatus); ?> Porém, quando eu executo o código NÂO é me retornado o array status com os indices com valores "0" ou "1", me retorna apenas uma nova chave FORA do array status com algum valor "0" ou "1". Tentei modificar o código ou tentar uma abordagem diferente, mas sem resultado. Vou inserir uma imagem para melhor compreensão do que o código me retorna.
       
       
      Espero ter sido claro na minha dúvida.  
      Desde já, agradeço.

×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.