Ir para conteúdo

Arquivado

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

danicarla

Encontrar registros não coincidentes, ajuda para melhor consulta

Recommended Posts

Oi pessoas.. preciso de ajuda para tentar melhorar essa consulta..

Eu tenho uma tabela que registra todas vendas feitas.. e preciso encontrar os clientes que fizeram compra no mês passado, mas que ainda não compraram esse mês..

Por enquanto eu estou fazendo assim:

<?php
$u = mysql_query("SELECT id_cliente FROM tab_vendas WHERE data_venda BETWEEN '2017-03-01' AND '2017-03-31' GROUP BY id_cliente");
while($r = mysql_fetch_assoc($u)){
              
  	// Consulta se tem venda no mês atual:
	$h = mysql_query("SELECT id_cliente,data_ultima_compra FROM tab_vendas 
    WHERE data_venda BETWEEN '2017-04-01' AND '2017-04-30' AND id_cliente=$r[id_cliente]");
  
  	  // Se não encontrar resultados exibe o cliente
      if (mysql_num_rows($h)==0) {
        $z = mysql_fetch_assoc($h);
        echo $z['id_cliente'].' - '.$z['data_ultima_compra'].'<br>';

      }  
  
}
?>

Essa consulta até funciona bem... mas quando eu pego uma tabela muito grande ela demora, e as vezes esgota o tempo do servidor.
Alguém tem alguma ideia de como posso melhorar isso?

Compartilhar este post


Link para o post
Compartilhar em outros sites

tenta usar COUNT na mesma pesquisa pra contar quem não comprou nesse mês

Compartilhar este post


Link para o post
Compartilhar em outros sites

A quantidade de resultados que $u trazer, sera o tanto de vezes que você terá que ir no banco, para obter $h

Se $u trazer 100 id_clientes, sera feita 100 consultas no banco.
Considerando que entendi o seu problema, da forma abaixo, sera feita apenas uma consulta! 
 

<?php
$u = mysql_query("
    SELECT id_cliente,data_ultima_compra 
    FROM tab_vendas 
    WHERE data_venda 
    BETWEEN '2017-04-01' AND '2017-04-30' 
    AND id_cliente 
    NOT IN(SELECT id_cliente 
        FROM tab_vendas 
        WHERE data_venda 
        BETWEEN '2017-03-01' AND '2017-03-31' 
        GROUP BY id_cliente)"
    );
while($z = mysql_fetch_assoc($u)){
    echo $z['id_cliente'].' - '.$z['data_ultima_compra'].'<br>';
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

EdCesar me parece que dessa forma vai trazer clientes que compraram no mês passado e também os que ainda não compraram esse mês e o que a colega quer é trazer só os que compraram no mês passado mas não compraram nesse mês. não tem que inverter os SELECT e botar NOT IN não?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Obrigado pela ajuda.. mudei a consulta da maneira que o Edcesar sugeriu e continuou lenta... Então eu criei um índice pro campo data_venda e resolveu...

Mas a minha duvida é... usando essa sub query ele também não vai fazer as 100 consultas no banco?
 

1 hora atrás, EdCesar disse:

Se $u trazer 100 id_clientes, sera feita 100 consultas no banco.

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

não no caso vai fazer uma consulta e trazer duma vez todos os resultados. imagina o seguinte tu tem uma pasta numa gaveta dum armário com 100 documentos. imagina se tu vai lá e pega dados desses documentos e bota cada um noutras 100 pastas. aí em duas consultas tu teria que pegar a pasta dos 100 documentos e depois procurar os outros 100 documentos. já sem fazer essa divisão tu vai buscar uma pasta só com tudo junto. ficou meio sem noção a comparação mas é só pra ilustrar a parada mesmo :smile:

Compartilhar este post


Link para o post
Compartilhar em outros sites
1 minuto atrás, danicarla disse:

Então eu criei um índice pro campo data_venda e resolveu...


Primeiro que bom que você resolveu! Mas nesse caso, então você tinha pelo menos dois problemas, sendo que o problema do indice era o principal.
 

3 minutos atrás, danicarla disse:

Mas a minha duvida é... usando essa sub query ele também não vai fazer as 100 consultas no banco?


No caso de 100 registros, usando a sub-query, trara os 100 registros em apenas uma consulta, da forma anterior, iria trazer os 100 registros, fazendo 100 consultas ao banco.

O Marsolim foi muito didático! 

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Jadilson o sexo do usuário é relevante onde em um forum de perguntas? (não deu pra ignorar :tounge_wink:)

 

@danicarla

Sobre o índice 'arrazou' kkkk eu to aprendendo muito sobre performance, veja se os links abaixo te ajudam nisso:

 

http://rberaldo.com.br/o-problema-do-n-mais-1/

 

Aqui tmb:

https://pt.stackoverflow.com/questions/6441/qual-é-a-diferença-entre-inner-join-e-outer-join

 

Lembrando que funções mysql_* estão obsoletas.

Recomendo atualizar as mesmas para PDO, ou Mysqli.

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

@gabrieldarezzo Nenhuma relevância meu caro... Apenas comentei o que observei.

Pena minha pergunta ainda não ter tido a atenção de ninguém. Vou comentar algo irrelevante lá também para ver se consigo.... 

De qualquer maneira devo desculpas a pessoa identificada como Dani Carla. De fato, não tem relevância a minha observação.

Compartilhar este post


Link para o post
Compartilhar em outros sites

  • Conteúdo Similar

    • Por landerbadi
      Boa tarde pessoal. Estou tentado fazer uma consulta no banco de dados porém estou tendo dificuldades. Tenho uma tabela chamada "itens" com os seguintes campos: id, item, ativo. Nela tem cadastrado vários itens. No campo ativo eu coloco a letra "S" para informar que este item está ativo no sistema. Por exemplo: 1, casa, S 2, mesa, S 3, cama, S 4, moto S 5, rádio O quinto registro "radio" não está ativo no sistema pois não tem um "S" no campo ativo. E outra tabela chamada "produtos" com os seguintes campos (id, item1, item2, item3) com os seguintes registros: 1, casa, mesa, moto 2, mesa, casa, cama 3, rádio, cama, mesa Eu preciso fazer uma busca na tabela produtos da seguinte maneira: Eu escolho um registro na tabela "itens", por exemplo "mesa". Preciso fazer com que o php me liste todos os registros da tabela "produtos" que contenham a palavra "mesa". Até aqui tudo bem eu consigo listar. Estou fazendo assim: <?php $item = "mesa" $sql = mysqli_query($conn, "SELECT * FROM produtos WHERE item1 LIKE '$item' OR item2 LIKE '$item' OR item3 LIKE '$item' LIMIT 10"); while($aux = mysqli_fetch_assoc($sql)) { $id = $aux["id"]; $item1 = $aux["item1"]; $item2 = $aux["item2"]; $item3 = $aux["item3"]; echo $id . " - " . $item1 . ", " . $item2 . ", " $item3 . "<br>"; } ?> O problema é que está listando todos os registros que contém o item mesa. Eu preciso que o php verifique os demais item e me liste somente os registro em que todos os registros estejam ativos no sistema. No exemplo acima ele não deveria listar o registro 3. pois nesse registro contém o item "radio" e este item não está ativo no sistema. Ou seja, o registro "radio" na tabela itens não possui um "S" na coluna "ativo". Alguém sabe como resolver isso?
    • Por ILR master
      Fala galera.
      Espero que todos estejam bem.
      Seguinte: Tenho um arquivo xml onde alguns campos estão com : (dois pontos), como o exemplo abaixo:
       
      <item>
      <title>
      d sa dsad sad sadasdas
      </title>
      <link>
      dsadas dsa sad asd as dsada
      </link>
      <pubDate>sadasdasdsa as</pubDate>
      <dc:creator>
      d sad sad sa ad as das
      </dc:creator>
      </item>
       
      Meu código:
       
      $link = "noticias.xml"; 
      $xml = simplexml_load_file($link); 
      foreach($xml -> channel as $ite) {     
           $titulo = $ite -> item->title;
           $urltitulo = $ite -> item->link;
           print $urltitulo = $ite -> item->dc:creator;
      } //fim do foreach
      ?>
       
      Esse campo dc:creator eu não consigo ler. Como faço?
       
      Agradeço quem puder me ajudar.
       
      Abs
       
       
    • Por First
      Olá a todos!
       
      Eu estou criando um sistema do zero mas estou encontnrando algumas dificuldades e não estou sabendo resolver, então vim recorrer ajuda de vocês.
      Aqui está todo o meu código: https://github.com/PauloJagata/aprendizado/
       
      Eu fiz um sistema de rotas mas só mostra o conteúdo da '/' não sei porque, quando eu tento acessar o register nada muda.
      E eu também quero que se não estiver liberado na rota mostra o erro de 404, mas quando eu tento acessar um link inválido, nada acontece.
      Alguém pode me ajudar com isso? E se tiver algumas sugestão para melhoria do código também estou aceitando.
       
       
      Desde já, obrigado.
×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.