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 blbvicente
      Olá amigos, gostaria de tirar uma dúvida para o andamento do meu projeto de conclusão de curso.
       
      Como posso fazer um código para alterar imagens no banco de dados via PHP e utilizando o MySQL com ambiente de admin?
       
      Como meu HTML e CSS estão prontos, (tanto a home quanto a página de login para o admin) a ultima parte que falta é conseguir fazer isso que lhes estou pedindo ajuda hahaha
       
      Desde já agradeço a ajuda! 
    • By granderodeo
      Olá, tenho uma tabela chamada products, com uma coluna chamada categorias. Dentro da coluna 'categorias' tenho produtos com categorias distintas como 'bebidas', 'doces', 'salgados', etc. Quero que o php retorne apenas os produtos com o categoria 'bebidas' isso é possível, ou devo criar uma tabela para cada categoria? No momento estou usando o código abaixo, mas ele me retorna todos os produtos, e eu só quero aqueles de determinada categoria.
       
      <?php $sql="SELECT * FROM product"; $result=$conn->query($sql); while($row=$result->fetch_assoc()){ ?> <div class="col-sm-6 col-md-4 col-lg-3 mb-2"> <div class="card-deck"> <div class="card p-2 border-secondary mb-2"> <img src="<?= $row['product_image']; ?>" class="card-img-top"> <p class="text-center"> <?= $row['product_name']; ?><br> </p> <h4 class="card-title text-center">Por : R$<?= $row['product_price'] ?></h4> <form accept-charset="utf-8" action="" class="form-submit"> <input type="hidden" class="pid" value="<?= $row['id'] ?>"> <input type="hidden" class="pname" value="<?= $row['product_name'] ?>"> <input type="hidden" class="pprice" value="<?= $row['product_price'] ?>"> <a href=""><input type="hidden" class="pimage" value="<?= $row['product_image'] ?>"></a> <input type="hidden" class="pcode" value="<?= $row['product_code'] ?>"> <button class="btn btn-success btn-block addItemBtn"><i class="fa fa-shopping-cart"></i> Adicionar ao Carrinho</button> </form> </div> </div> </div> <?php } ?>  
    • By douglas79
      Boa noite pessoal,
      Estou seguindo um livro em PHP,  existe um campo pra inserir a imagem de um determinado produto. Fiz um formulário como teste e juntei uns códigos que achei na internet e até está dando certo, os dados estão indo pro BD. Mas tenho duas dúvidas e queria a ajuda do pessoal. Uma é colocar a sequencia nas fotos quando cadastrados (exemplo foto01, foto02 .... foto n) e ao inserir a imagem que é somente pode imagem com a suas extensões e uma mensagem informando.

      Eis o código:
       
      <?php
      include "conn.php";
      $nome = $_POST['nome'];
      $email = $_POST['email'];
      $foto = $_FILES['foto'];
      $pasta = "img/";

      $sql = "INSERT INTO cad (nome,email,foto) VALUES ('".$nome."','".$email."','".$_FILES['foto']['name']."')";
      mysql_query($sql,$con);
      $nome_final = time(). '.jpg';
      if (move_uploaded_file($foto['tmp_name'], $pasta . $nome_final)) {
          
          header("location:index.php");
      } else {
          echo "Erro";
      }
      ?>
      Aguardo as ajudas, desde já obrigado! []'s
    • By Hugo_Santos
      Preciso fazer uma consulta em um banco com 7 milhões de registros, mais precisamente 7.387.951 milhões, já adicionei as devidas index porém continua muito lento, será que alguem poderia me ajudar?
       
       
      SELECT a.nome_candidato,a.numero_cand,a.sigla_partido,SUM(a.total_votos) as total_votos,a.ds_tot_turno FROM votacao_candidato a WHERE a.ds_cargo='Deputado Estadual' AND a.sigla_uf='SP' AND a.nome_municipio='santos' AND a.desc_sit_candidato='DEFERIDO' GROUP BY a.sq_candidato ORDER BY a.total_votos DESC LIMIT 10
    • By granderodeo
      Olá  meus amigos programadores, estou desenvolvendo uma loja virtual, e percebi um erro. Criei um banco de dados  chamado 'cart_system' , com uma tabela 'cart'. Coloquei o site online para fazer testes, e coloquei os produtos normalmente no carrinho, mas ao abrir em outro PC o site, estava o mesmo carrinho, por exemplo coloquei 5 produtos em um PC e quando abrir o site em outro PC estava os mesmos 5 produtos já adicionados. Assim que adiciona o produto é adicionado ao 'cart' no BD, e quando for ver os produtos ele puxa do BD os produtos que estão atualmente no 'cart', será que foi esse o meu erro. Se puderem me ajudar com maneiras de concertar esse erro, agradeço muito. Vou deixar abaixo os códigos.
       
      Javascript do index.php que adiciona os produtos ao carrinho
      <script type="text/javascript"> $(document).ready(function(){ $(".addItemBtn").click(function(e){ e.preventDefault(); var $form = $(this).closest(".form-submit"); var pid = $form.find(".pid").val(); var pname = $form.find(".pname").val(); var pprice = $form.find(".pprice").val(); var pimage = $form.find(".pimage").val(); var pcode = $form.find(".pcode").val(); $.ajax({ url: 'carrinho/action_car.php', method: 'post', data: {pid:pid,pname:pname,pprice:pprice,pimage:pimage,pcode:pcode}, success:function(response){ $("#message").html(response); window.scrollTo(0,0); load_cart_item_number(); } }); }); load_cart_item_number(); function load_cart_item_number(){ $.ajax({ url: 'carrinho/action_car.php', method: 'get', data: {cartItem:"cart_item"}, success:function(response){ $("#cart-item").html(response); } }); } }); </script>  
      index_cart.php
      <div class="container"> <div class="row justify-content-center"> <div class="col-lg-10"> <div style="display:<?php if(isset($_SESSION['showAlert'])){echo $_SESSION['showAlert'];}else { echo 'none'; } unset($_SESSION['showAlert']); ?>" class="alert alert-success alert-dismissible mt-3"> <button type="button" class="close" data-dismiss="alert">&times;</button> <strong><?php if(isset($_SESSION['message'])){echo $_SESSION['message'];} unset($_SESSION['showAlert']); ?></strong> </div> <div class="table-responsive mt-2"> <table class="table table-bordered table-striped text-center"> <thead> <tr> <td colspan="7"> <h4 class="text-center text-info m-0">Produtos em seu carrinho!</h4> </td> </tr> <tr> <th>ID</th> <th>Imagem</th> <th>Produto</th> <th>Preço</th> <th>Quantidade</th> <th>Valor Total</th> <!------ REMOVER TODOS ITENS DO CARRINHO -----> <th> <a href="action_car.php?clear=all" class="badge-danger badge p-1" onclick="return confirm('Tem certeza de que deseja limpar seu carrinho?');"> <i class="fa fa-trash"></i>&nbsp;&nbsp;Limpar Carrinho</a> </th> <!------ FIM REMOVER TODOS ITENS DO CARRINHO -----> </tr> </thead> <tbody> <?php require 'config_car.php'; $stmt = $conn->prepare("SELECT * FROM cart"); $stmt->execute(); $result = $stmt->get_result(); $grand_total = 0; while($row = $result->fetch_assoc()): ?> <tr> <td> <?= $row['id'] ?></td> <!-- ID do produto do BD para o carrinho --> <input type="hidden" class="pid" value="<?= $row['id'] ?>"> <td> <img src="../<?= $row['product_image'] ?>" height="50"> </td> <!-- chamada da imagem do BD para o carrinho --> <td><?= $row['product_name'] ?> </td> <td> <?= $row['product_price'] ?> </td> <input type="hidden" class="pprice" value="<?= $row['product_price'] ?>"> </td> <!---- Aumentar ou Diminuir a quantidade do produto -----> <td><input type="number" class="form-control itemQty" value="<?= $row['qty'] ?>" style="width:80px"></td> <!---- Aumentar ou Diminuir a quantidade do produto -----> <!---- Fim Aumentar ou Diminuir a quantidade do produto -----> <td><?= $row['total_price'] ?> </td> <!-- preço total do carrinho --> <!------- REMOVER ITEM DO CARRINHO ------> <td> <a href="action_car.php?remove=<?= $row['id'] ?>" class="text-danger lead" onclick="return confirm('Quer mesmo remover esse produto do carrinho?');"> <i class="fa fa-trash"></i></a> </td> <!------- FIM ITEM REMOVER DO CARRINHO -------> </tr> <?php $grand_total += $row['total_price'] ?> <?php endwhile; ?> <tr> <td colspan="3"> <a href="../index.php" class="btn btn-success"><i class="fa fa-cart-plus"></i>&nbsp;&nbsp;Continue Comprando</a> </td> <td colspan="2"><b>Total Geral</b></td> <td><?= number_format($grand_total); ?> </td> <td> <a href="finalizar_car.php" class="btn btn-info <?= ($grand_total>1)?"":"disabled"; ?>"><i class="fa fa-credit-card"></i>&nbsp;&nbsp;Finalizar Compra</a> </td> </tr> </tbody> </table> </div> </div> </div> </div>  
      action_car.php
      <?php session_start();     require 'config_car.php'; //conecta ao BD     if(isset($_POST['pid'])) {         $pid = $_POST['pid'];         $pname = $_POST['pname'];         $pprice = $_POST['pprice'];         $pimage = $_POST['pimage'];         $pcode = $_POST['pcode'];         $pqty = 1;         $stmt = $conn->prepare("SELECT product_code FROM cart WHERE product_code=?");         $stmt->bind_param("s",$pcode);         $stmt->execute();         $res = $stmt->get_result();         $r = $res->fetch_assoc();         $code = $r['product_code'];         if(!$code){             $query = $conn->prepare("INSERT INTO cart (product_name,product_price,product_image,qty,total_price,product_code) VALUES (?,?,?,?,?,?)");             $query->bind_param("sssiss",$pname,$pprice,$pimage,$pqty,$pprice,$pcode);             $query->execute();             echo '<div class="alert alert-success alert-dismissible mt-2">             <button type="button" class="close" data-dismiss="alert">&times;</button>             <strong>Item adicionado ao seu carrinho!</strong>             </div>';         }         else{             echo '<div class="alert alert-danger alert-dismissible fixed-top">             <button type="button" class="close" data-dismiss="alert">&times;</button>             <strong>Item já está adicionado ao seu carrinho, você pode definir a quantidade no seu carrinho!</strong>             </div>';         }     }     if(isset($_GET['cartItem']) && isset($_GET['cartItem']) == 'cart_item'){         $stmt = $conn->prepare("SELECT * FROM cart");         $stmt->execute();         $stmt->store_result();         $rows = $stmt->num_rows;         echo $rows;     }     /*REMOVER ITENS DO CARRINHO*/     if(isset($_GET['remove'])){         $id = $_GET['remove'];         $stmt = $conn->prepare("DELETE FROM cart WHERE id=?");         $stmt->bind_param("i",$id);         $stmt->execute();         $_SESSION['showAlert'] = 'block';         $_SESSION['message'] = 'Produto removido do carrinho!';         header('location:index_cart.php');     }     if(isset($_GET['clear'])){         $stmt = $conn->prepare("DELETE FROM cart");         $stmt->execute();         $_SESSION['showAlert'] = 'block';         $_SESSION['message'] = 'Todos os produtos foram removidos!';         header('location:index_cart.php');     }      /* FIM REMOVER ITENS DO CARRINHO*/     /* ADICIONAR OU DIMINUIR QTD PRODUTO CARRINHO*/     if(isset($_POST['qty'])){         $qty = $_POST['qty'];         $pid = $_POST['pid'];         $pprice = $_POST['pprice'];         $tprice = $qty*$pprice;         $stmt = $conn->prepare("UPDATE cart SET qty=?, total_price=? WHERE id=?")         ;         $stmt->bind_param("isi",$qty,$tprice,$pid);         $stmt->execute();     }      /* FIM ADICIONAR OU DIMINUIR QTD PRODUTO CARRINHO*/      /* FINALIZAR PEDIDO */      if(isset($_POST['action']) && isset($_POST['action']) == 'order'){          $name = $_POST['name'];          $email = $_POST['email'];          $phone = $_POST['phone'];          $products = $_POST['products'];          $grand_total = $_POST['grand_total'];          $address = $_POST['address'];          $pmode = $_POST['pmode'];          $data = '';          $stmt = $conn->prepare("INSERT INTO orders (name,email,phone,address,pmode,products,amount_paid) VALUES (?,?,?,?,?,?,?)");          $stmt->bind_param("sssssss",$name,$email,$phone,$address,$pmode,$products,$grand_total);          $stmt->execute();          $data .= '<div class="text-center>                         <h1 class="display-4 mt-2 text-danger">Obrigado!</h1>                         <h2 class="text-success">Seu pedido foi realizado com sucesso</h2>                         <h4 class="bg-danger text-light rounded p-2">Items Comprados : '.$products.'</h4>                         <h4 class="bg-danger text-light rounded p-2">Seu nome : '.$name.'</h4>                         <h4 class="bg-danger text-light rounded p-2">Seu E-mail : '.$email.'</h4>                         <h4 class="bg-danger text-light rounded p-2">Seu telefone : '.$phone.'</h4>                         <h4 class="bg-danger text-light rounded p-2">Valor total pago : '.number_format($grand_total,2).'</h4>                         <h4 class="bg-danger text-light rounded p-2">Forma de pagamento : '.$pmode.'</h4>                    </div>';         echo $data;                 }      ?>  
×

Important Information

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