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 guzulino
      Eu preciso criar um sistema de busca em tempo real vamos dizer assim, na realidade eu até consegui achar boa parte dele.
      <form onsubmit="return false;"> <input id="campo_cpu" type="text" name="nome_cpu" placeholder="Modelo do processador"> </form> <script src="auto-complete.js"></script> <script> var demo1 = new autoComplete({ selector: '#campo_cpu', minChars: 1, source: function(term, suggest){ term = term.toLowerCase(); var choices = ['ActionScript', 'AppleScript', 'Asp', 'Assembly', 'BASIC', 'Batch', 'C', 'C++', 'CSS', 'Clojure', 'COBOL', 'ColdFusion', 'Erlang', 'Fortran', 'Groovy', 'Haskell', 'HTML', 'Java', 'JavaScript', 'Lisp', 'Perl', 'PHP', 'PowerShell', 'Python', 'Ruby', 'Scala', 'Scheme', 'SQL', 'TeX', 'XML']; var suggestions = []; for (i=0;i<choices.length;i++) if (~choices[i].toLowerCase().indexOf(term)) suggestions.push(choices[i]); suggest(suggestions); } }); </script> Eu consegui esse código e ele funciona tranquilamente, mas isso é só um teste, o usuário vai digitar o que ele precisa e no banco de dados eu mais de 5000 registros, então eu preciso que seja feita uma consulta no banco de dados para que ele mostre o que tem lá, acho que colocar 5000 numa string é um #@?&#036;%~ trampo além de eu achar que vai dar caquinha, o problema é que eu não faço a mínima ideia de como fazer isso, eu acho que é tipo uma consulta no banco a cada caractére digitado mostrando somente os resultados compatíveis, mas como disse antes não tenho ideia, se alguém agradeço desde já. Valeu
    • By MatheusSmidt
      Bom dia,
      Estou precisando de ajuda com o código do formulário de um sistema de cadastro.
      A página é para consulta mas tem a possibilidade de adicionar ou retirar "faltas" de cada profissional cadastrado através de botões simples e também apagar um ou múltiplos profissionais da lista, através de checkbox..
      Essa ações atualizam o banco de dados e já retornam na tela automaticamente.
      O problema é que não fui eu que estruturei o código PHP e não consigo aliar as duas funções que falei anteriormente. Quando consigo fazer funcionar o sistema de adição e redução de faltas, consigo apenas excluir o último nome da lista, mesmo selecionando vários. E quando consigo resolver a parte de excluir vários nomes, não consigo adicionar e reduzir o número de faltas.
      O código é o seguinte:
       
      <?php
      require_once ("verifica.php");
      require_once ("topo.php");
      require_once ("conexao.php");
      $enviar = isset($_POST["txtEnviar"]) ? $_POST["txtEnviar"]: '';
      $ordenar = isset($_GET["ordenar"]) ? $_GET["ordenar"]: '';
      if ($ordenar == "")
          $ordenar = "nome";
      if ($enviar != 1) {
          $query = mysql_query("select * from docente order by $ordenar") or die ("Erro ao selecionar dados do docente! ".mysql_error());
      } else {
          $rdCriterio = $_POST["rdCriterio"];
          $pesquisar = $_POST["txtPesquisar"];
          $query = mysql_query("select * from docente where $rdCriterio like '%$pesquisar%'") or die ("Erro ao efetuar a pesquisa! ".mysql_error());
      }
      $totalDocentes = mysql_num_rows(mysql_query("select * from docente"));
      ?>
      <div id="meio">
          <h2>Lista de docentes (<?php echo $totalDocentes;?>)</h2><br>
          <table id="tbPesquisarDocente">
          <form action=consultarDocente.php method=post>
          <input type=hidden name=txtEnviar value=1>
          <tr>
          <td id=search>Pesquisar por: <input type=radio name=rdCriterio value="siape" checked>Siape <input type=radio name=rdCriterio value="nome"> Nome <input type=radio name=rdCriterio value="curso">Curso <input type=text name=txtPesquisar> <input type=submit value="OK"></td>
          </tr>
          </form>
          </table>
          <br><br>
          <table id="dadosDocente" cellspacing=0>
          <form action="consultarDocente.php" method="post">
          <tr id="cabecalho">
          <td><a href="?ordenar=siape">Siape</a></td>
          <td><a href="?ordenar=nome">Nome</a></td>
          <td><a href="?ordenar=curso">Curso</a></td>
          <td><a href="?ordenar=faltas">Faltas</a></td>
          <td><a href="?ordenar=excluir">Excluir</a></td>
          <td><!-- Espaço para checkbox --></td>
          </tr>
          <?php
          while ($resultado = mysql_fetch_array($query)) {
              $id = $resultado["id"];
              $siape = $resultado["siape"];
              $nome = $resultado["nome"];
              $curso = $resultado["curso"];
              $faltas = $resultado["faltas"];
          ?>
          </form>
          <tr id="dados" bgcolor="">
          <td><a href="frmDetalheDocente.php?id=<?php echo $id;?>" style="color: <?php echo $cor;?>"><?php echo $siape;?></style></a></td>
          <td><?php echo $nome;?></td>
          <td><?php echo $curso;?></td>
          
          <td align="center">
              <table>
                  <tr>
                      <td><a href="menosum.php?id=<?php print $id;?>"><button name="Btt" style="width:10px">-</button></a></td>
                      <td><?php echo $faltas?></td>
                      <td><a href="maisum.php?id=<?php print $id;?>"><button name="Btt" style="width:10px">+</button></a></td>
                  </tr>
              </table>
          </td>
          
          <form action="apagaSelecionadosDocente.php" method="post">
          <td><input type="checkbox" name="chkDeletar[]" value="<?php echo $id;?>"></td>
          </tr>
          <?php
          }
          ?>
          
          <tr>
          <td colspan=4 align="center"><br><input type="submit" value="Apagar selecionados" style="width: 300px;"></td>
          </tr>
          </form>
          </table>
      </div>
      <?php
      require_once ("rodape.php");
      ?>
       
       
      Provavelmente é um problema no "WHILE" ou na abertura e fechamento de formulário. Porém não consegui resolver.
      Se alguém conseguir resolver seria ótimo.
      Agradeço desde já. Em anexo envio um print da página para melhor entendimento.
       
       
       

    • By Guilherme Scarpatto
      <p>Escolha a categoria: <select name="categoria"> <option></option> <option value="v1">Conhecimentos gerais</option> <option value="v2">Português</option> <option value="v3">Matemática</option> <option value="v4">História</option> <option value="v5">Geografia</option> <option value="v6">Sociologia</option> <option value="v7">Tecnologia</option> <option value="v8">Biologia</option> <option value="v9">Programação</option> <option value="v10">Banco de dados</option> </select>  
    • By jeandelima
      Olá pessoal, estava querendo saber se podem me ajudar com uma pequena dúvida que surgiu há poucos dias.
       
      Estou com problemas pra importar um banco de dados pra o usar no meu servidor local (xampp). O banco de dados foi exportado do site de um cliente, e lá no server eles usam o mysql. Instalei a versão mais recente do xampp no meu pc, e quando fui importar o banco pra poder começar os trabalhos, deu vários erros de sintaxe. Daí fiz umas pesquisas e encontrei alguns materiais que mencionavam que o xampp agora usa o mariadb, e ele não é 100% compatível com mysql.
       
      Estou há um bom tempo sem mexer com programação e também sem me atualizar das coisas, e gostaria de saber se alguém sabe a partir de qual versão do xampp eles passaram a usar o mariadb. Eu já pesquisei mas não obtiver sucesso. E instalar e desinstalar inúmeras versões é algo trabalhoso e cansativo demais. Alguém poderia me ajudar?
       
      Desde já, muito obrigado.
       
      PS.: Por ser novo aqui no forum, e por não frequentar forum há muito tempo, acho que acabei postando no lugar errado. Peço perdão aos adms.
    • By Good
      Boa tarde,
       
      temos um servidor na amazon, e o site está direcionado para o servidor. Estamos tendo um problema, de vez em quando o servidor cai. 
       
      Gostaríamos de saber se tem algum programa no ubuntu, que monitore qual arquivo que teve alto consumo. Para sabermos se o código está escrito de maneira complexa, causando a queda do servidor.
       
      Eu lembro que uma vez a hostgator mandou um relatório, avisando que tal arquivo estava consumindo muito do servidor. É possível fazer esse monitoramento? Não temos como ficar 24h olhando por exemplo o htop..
       
      Aguardo uma resposta,
      obrigado!
×

Important Information

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