Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Olá Professionals Web!
Não é atoa que os programadores detestam fazer a parte de relatórios de suas aplicações.
Bom e hoje me deparo com tal desafio e gostaria da ajuda de vocês por favor.
Tenho na tela umas 4 caixas de seleção(tag select > option) e 2 text-field para escolher o periodo por datas.
Ai com base em TODOS os campos preenchidos ou PARTE deles eu gero um resultado.
É nessa parte que está enroscando... Vou postar abaixo a teoria base da minha consulta, e vejam o que eu preciso...
$buscando_vendas = mysql_query("SELECT * FROM venda_cadastro WHERE (produto_A = 'Venda' OR produto_B = 'Venda' OR produto_C = 'Venda') AND data BETWEEN('$data_de') AND ('$data_ate') AND id_user = '$id_user' ORDER BY id DESC");
Minha consulta é essa basicamente, o problema é que não funciona como deveria, pois quando um dos OR se torna verdadeiro ele anula todo o resto da consulta e acaba trazendo dados incompletos ou nem chega gerar resultados.
Ou seja eu preciso consultar o id_user, o periodo entre as 2 datas e se os campos de produtos(a,b ou c) são todos ou parte deles "Venda"... Lembrando que talvez a pessoa que vai tirar o relatorio escolha somente o usuario, sem datas ou status dos produtos. Traduzindo, tem que ser algo flexivel, preenchendo tudo ou apenas 1 campo ou 2 do relatorio.
Como devo proceder? Qual a melhor maneira de gerar relatorios deste tipo?
Conto com a ajuda de vocês.
Desde já agradeço.
É tratado sim, eu só postei a query final...
Mas vamos lá.... como vc faria no meu caso? Qual seu metodo? Ou alguem que queria compartilhar o metodo por favor?
Baseando se na tabela que falei meio por cima...
Boa Madrugada,
Primeiramente você precisa utiliza o PDO para conexao com o banco de dados, assim você tem um leque de opções para definir se os parametros estão chegando ou não, se estão sendo tradados com métodos do proprio PDO.
Primeiramente Conexao com o PDO:
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test','root','');
Agora vamos Fazer o SQL:
try{
$sql = $pdo->prepare("
SELECT * FORM venda_cadastro WHERE
(produto_A = :a || produto_B = :b || produto_C = :c) &&
data between :data_a and data_b and id_user = :user
order by id desc
");
$sql->bindValue(":a", $valor_a);
$sql->bindValue(":b", $valor_b);
$sql->bindValue(":c", $valor_c);
$sql->bindValue(":data_a", $data_a);
$sql->bindValue(":data_b", $data_b);
$sql->bindValue(":user", $user);
$sql->execute();
}catch(PDOException $e){
echo $e->getMessage();
}
Assim se você utilizar o try/catch você pode tentar compreender qual erros está acontencendo.. Caso tenha dúvidas sobre o PDO.
Você também pode utilizar métodos para identificar os erros que estão ocorrendo no seu comando SQL:
PDOStatement::errorCode
http://www.php.net/manual/pt_BR/pdostatement.errorcode.php
PDOStatement::errorInfo
http://www.php.net/manual/pt_BR/pdostatement.errorinfo.php
Documentação do PDO
Vish ai complicou, nao posso mudar meu sistema inteiro para PDO, mudar inteiro por causa de 1 tela da aplicação.
Eu reconheço que PDO é mto bom, mas na "altura do jogo" migrar é inviável.
Não tem como fazer da maneira convencional?
Grato pela atenção e disposição em ajudar.
Essa semana encontrei o mesmo problema ao gerar relatório de uma aplicação que criei, depois de 2 dias me matando em uma única query, descobri que o problema não estava no meu código e sim nos usuários que usaram o sistema, isso me deixou realmente muito p... enfim, no seu caso eu usaria if pra validar e montar e montar a query de acordo, mas não sei se a sua já está assim.
Poste seu código PHP também para entendermos como está fazendo. :)
Caramba esses usuarios hein kkkk
Vamos lá, aqui está o esboço inicial do script...
<?php
include "funcoes/conexao.php";
$data_de_temp = explode('/', $_POST['data_de']);
$data_de = $data_de_temp[2].'-'.$data_de_temp[1].'-'.$data_de_temp[0];
$data_ate_temp = explode('/', $_POST['data_ate']);
$data_ate = $data_ate_temp[2].'-'.$data_ate_temp[1].'-'.$data_ate_temp[0];
$selecione_venda = $_POST['selecione_venda'];
$selecione_ligacao = $_POST['selecione_ligacao'];
$selecione_vendedor = $_POST['selecione_vendedor'];
$buscando_vendas = mysql_query("SELECT * FROM venda_cadastro WHERE (produto_A = '$selecione_venda' OR produto_B = '$selecione_venda' OR produto_C = '$selecione_venda') AND data BETWEEN('$data_de') AND ('$data_de') AND origem = '$selecione_ligacao' AND id_user = '$selecione_vendedor' ORDER BY id DESC");
while($resultado = mysql_fetch_array($buscando_vendas)) {
?>
Iai "José", oque me diz?
Abraços e obrigado pela atenção.
Você já testou sua query no seu SGBD usando valores fixos?
Sim e o pior é que a lazarenta funciona...
Tente fazer verificação dos campos se estão preenchidos ou nulos, ai de acordo com isso, ele cria uma query diferente.
Achei um problema na sua query, mas acredito que não seja o problema.
Está assim:
data BETWEEN('$data_de') AND ('$data_de')
Deveria ser assim:
data BETWEEN('$data_de') AND ('$data_ate')
Concatenar as variáveis é seguro e ajuda também.
Realmente nesse detalhe que vc mencionou nao é o problema, eu passei errado mesmo a variavel na postagem, no meu codigo esta correto.
Cheguei implantar uma verificação de campos vazios ou nulos... mas depois de varias analises notei que o problema ocorre quando um dos OR's se torna verdadeiro ai ele para a query ali.... ai gera os resultado se possivel. Mas fica enroscando pois nunca funciona de forma eficiente.
Então vezes ele trazia algumas informações e outro hora nao trazia nada.
Foi por isso que o teste no SGDB com valores fixos funciona pois não depende exatamente dos OR's.
Cheguei criar um esquema de concatenar variaveis mas caia na questao de quando o OR se torna verdadeiro.
Ta tenso viu...
Deixa eu ver se entendi, se ele não encontra nada no produto a ele tenta o produto b e assim com o c. É isso? Ou ele procura o mesmo valor no produto a, b e c?
A minha ideia é que consulte os 3 campos e ve se conta o "Vender" em algum deles para poder exibir o registro.
E ao mesmo tempo ele verifica os demais campos(id_usuario, origem, data etc...) e pode acontecer do usuario nao querer filtrar por exemplo origem e data e sim apenas o vendedor(id_usuario) ....
Ta foda isso... Eu cheguei alterar a ordem dos AND e OR e teve uma certa relevância principalmente na parte do:
(produto_A = '$selecione_venda' OR produto_B = '$selecione_venda' OR produto_C = '$selecione_venda')
Mas ainda não consegui chegar no resultado ideal...
Para vc ter uma ideia minha tabela é assim:
ID - produto_A - produto_B - produto_B - data - origem - id_usuario
1 Venda Reprovado Venda 2013-03-27 Ligação 123
2 Venda Reprovado Venda 2013-03-27 Ligação 122
3 Venda Venda Venda 2013-03-26 Ligação 123
4 Venda Reprovado Venda 2013-03-27 Ligação 122
5 Venda Venda Venda 2013-03-26 Ligação 123
Ai tenho uma tela com os select > options(para cada produto[a,b,c]) e para cada coluna e assim escolho o termo a ser filtrado...
O usuario pode preencher parte deles ou não... como tornar isso flexivel? Não descobri isso ainda rsrsrs
O que eu perecebi que faz o erro gerar é que se um dos OR dos produtos se torna verdadeiro, ele anula o resto da query e faz a consulta só com aquilo que deu verdadeiro.
Bom, posso estar errado, mas foi o que eu identifiquei como erro.
O que acha?
Captura o valor do seu select do produto (a, b ou c) e cria um switch que altera a query, por exemplo:
<?php
$produto = $_POST['produto'];
switch($produto){
case "a":
$buscando_vendas = mysql_query("SELECT * FROM venda_cadastro WHERE (produto_A = '".$selecione_venda."') AND (data BETWEEN '".$data_de."' AND '".$data_de."' AND origem = '".$selecione_ligacao."' AND id_user = '".$selecione_vendedor."' ORDER BY id DESC");
break;
case "b":
$buscando_vendas = mysql_query("SELECT * FROM venda_cadastro WHERE (produto_B = '".$selecione_venda."') AND (data BETWEEN '".$data_de."' AND '".$data_de."' AND origem = '".$selecione_ligacao."' AND id_user = '".$selecione_vendedor."' ORDER BY id DESC");
break;
case "c":
$buscando_vendas = mysql_query("SELECT * FROM venda_cadastro WHERE (produto_C = '".$selecione_venda."') AND (data BETWEEN '".$data_de."' AND '".$data_de."' AND origem = '".$selecione_ligacao."' AND id_user = '".$selecione_vendedor."' ORDER BY id DESC");
break;
?>
Acho que assim funciona.
Acho que seu problema é o seguinte você que todos os produtos que contenhas $selecione_venda independentes se esta no produto (a, b ou c).
Acho que com UNION ALL funciona legals o que você quer.
Como o proprio nome em si ja diz union une duas ou mais tabelas nesse caso ele iria unir a mesma tabela só que com consultas diferentes.
Vou postrar um exemplo adapte ao seu código.
$buscando_vendas = mysql_query("(SELECT * FROM venda_cadastro WHERE produto_A = '$selecione_venda' AND (data BETWEEN '".$data_de."' AND '".$data_de."' AND origem = '".$selecione_ligacao."' AND id_user = '".$selecione_vendedor."' ORDER BY id DESC) UNION ALL (SELECT * FROM venda_cadastro WHERE produto_B = '$selecione_venda' AND (data BETWEEN '".$data_de."' AND '".$data_de."' AND origem = '".$selecione_ligacao."' AND id_user = '".$selecione_vendedor."' ORDER BY id DESC)");
http://dev.mysql.com/doc/refman/5.0/en/union.htmlRicardo Saraiva
Sua solução aparentemente esta funcionando... Muito boa essa ténica.
Agora estou enroscando nas clausulas AND, pois no seu exemplo, estamos tratando de valores "fixos", agora tenho que ver uma forma de realizar a consulta e usar o AND caso seja necessario pois o usuario pode ou não preencher todos os campos para gerar um relatorio, por conta dele só selecionar os campos que ele achar necessario para gerar seu relatório.
Vc tem alguma tatica para isso?
Cara um conselho que dou pra vc. não sei se vc conhece, eu uso como gerador de relatórios o JasperReports, ele é pra java, porém ele tem uma biblioteca que chama PHPJASPERXML, qie vc integra ele com o java. O jasper é super facil d usar, e montar os relatórios. Qqr duvida me fale ou contate-me. ABS
Cara geralmente eu uso condições em (if, elseif e else), Ai dependendo de cada resultado eu criou um sql diferente.
Vish pessoal...
Nao ta dando certo não....
Agora ele exibe resultados duplicados, tentei usar o DISTINCT mas nem rolou, ainda mostra duplicados... e ainda to enroscando na questão dos if e else para usar a clausula AND quando necessario na query.... :/
Ô coisa chata de fazer esse tal de relatório...
Alguem por favor?
>
Vish pessoal...
Nao ta dando certo não....
Agora ele exibe resultados duplicados, tentei usar o DISTINCT mas nem rolou, ainda mostra duplicados... e ainda to enroscando na questão dos if e else para usar a clausula AND quando necessario na query.... :/
Ô coisa chata de fazer esse tal de relatório...
Alguem por favor?
Olá, preciso fazer essa mesma ideia para gerar um relatório, porém não consigo montar uma query funcional.
Você conseguiu resolver?
Mas na sua query não é tratado nada, como vc sabe se ele preencheu ou não