Problema com data no Select?
Pessoal tenho uma tabela assim
Cada ´V´ deste ai fica em uma coluna
então montei uma select para trazer o count de cada coluna
o resultado é este do select
Mais por exemplo se eu colocar esta linha aqui
[b:e929ec48b0]--and a.dtmovimento >= ´01/11/2008´ and a.dtmovimento <= [/b:e929ec48b0]´01/11/2008´
ou usar o between
[b:e929ec48b0]--between :pdtIn and :pdtFn
[/b:e929ec48b0]
Com data de 01/11/2008 a 01/11/2008, não esta me trazendo o resultado correto
que seria
e não
Ou seja ele esta pegando a ID certa que tem no dia 01/11/2008, mais esta somando tudo e não só o que esta naquela coluna.
Então pessoal, como faço para contar os valores corretos cfe. a data?
Obs: Estou usando Firebird 2.0 e ainda não testei no projeto, estou testando diretamente no IBExpert
1 13 3 03.11.2008 V V V V
2 13 2 05.11.2008 V V
4 13 2 07.11.2008 V V
14 13 2 04.11.2008 V
15 13 3 05.11.2008 V
18 13 2 06.11.2008 V V V V
25 13 3 01.11.2008 V V V V V V
1
01/11/2008 23:37:42
Cada ´V´ deste ai fica em uma coluna
então montei uma select para trazer o count de cada coluna
select distinct(a.idcaixa), b.nmcaixa, ( select count(vdnaofinalizada) from movimento where b.idcaixa = idcaixa and vdnaofinalizada = ´V´ )as vdnaofinalizado, ( select count(cxnaoinformado) from movimento where b.idcaixa = idcaixa and cxnaoinformado = ´V´ )as CxNaoInformado, ( select count(inversaopgto) from movimento where b.idcaixa = idcaixa and inversaopgto = ´V´ )as InversaoPgto, ( select count(vdfinaldeumdiapoutro) from movimento where b.idcaixa = idcaixa and vdfinaldeumdiapoutro = ´V´ )as vdfinaldeumdiapoutro, ( select count(cxinfemdterrada) from movimento where b.idcaixa = idcaixa and cxinfemdterrada = ´V´ )as cxinfemdterrada, ( select count(vlinformadocorretamente) from movimento where b.idcaixa = idcaixa and vlinformadocorretamente = ´V´ )as vlinformadocorretamente from movimento a, respcaixa b where b.idcaixa = a.idcaixa --and a.idcaixa = :varID --and a.dtmovimento >= ´01/11/2008´ and a.dtmovimento <= ´01/11/2008´ --between :pdtIn and :pdtFn and a.cxnaoinformado = ´V´
o resultado é este do select
2 teste2cc mns 3 1 0 2 1 2
3 mn 1 3 1 2 2 2
1
01/11/2008 23:43:26
Mais por exemplo se eu colocar esta linha aqui
[b:e929ec48b0]--and a.dtmovimento >= ´01/11/2008´ and a.dtmovimento <= [/b:e929ec48b0]´01/11/2008´
ou usar o between
[b:e929ec48b0]--between :pdtIn and :pdtFn
[/b:e929ec48b0]
Com data de 01/11/2008 a 01/11/2008, não esta me trazendo o resultado correto
que seria
3 mn 1 1 1 1 1 1
1
e não
3 mn 1 3 1 2 2 2
1
Ou seja ele esta pegando a ID certa que tem no dia 01/11/2008, mais esta somando tudo e não só o que esta naquela coluna.
Então pessoal, como faço para contar os valores corretos cfe. a data?
Obs: Estou usando Firebird 2.0 e ainda não testei no projeto, estou testando diretamente no IBExpert
Adriano_servitec
Curtidas 0
Respostas
Adriano_servitec
02/11/2008
Mesma coisa no aplicativo, ainda não deu certo, achei que poderia ser conversão de datas, mais não é
Creio que esteja errado o select
var
DataIn, DataFn : TDate;
begin
inherited;
{Passando as datas para variaveis}
DataIn := StrToDate(MaskEdit1.Text);
DataFn := StrToDate(MaskEdit2.Text);
with IBQListCaixa do
begin
Close;
Sql.Clear;
Sql.Text := ´ select distinct(a.idcaixa), b.nmcaixa, ´+
´ ( select count(vdnaofinalizada) ´ +
´ from movimento ´+
´ where b.idcaixa = idcaixa and vdnaofinalizada = ´´V´´ )as vdnaofinalizado, ´ +
´ ( select count(cxnaoinformado) ´+
´ from movimento ´+
´ where b.idcaixa = idcaixa ´ +
´ and cxnaoinformado = ´´V´´ )as CxNaoInformado, ´+
´ ( select count(inversaopgto) ´ +
´ from movimento ´+
´ where b.idcaixa = idcaixa and inversaopgto = ´´V´´ )as InversaoPgto, ´ +
´ ( select count(vdfinaldeumdiapoutro) ´+
´ from movimento where b.idcaixa = idcaixa ´ +
´ and vdfinaldeumdiapoutro = ´´V´´ )as vdfinaldeumdiapoutro, ´ +
´ ( select count(cxinfemdterrada) ´+
´ from movimento where b.idcaixa = idcaixa ´ +
´ and cxinfemdterrada = ´´V´´ )as cxinfemdterrada, ´ +
´ ( select count(vlinformadocorretamente) ´+
´ from movimento where b.idcaixa = idcaixa ´ +
´ and vlinformadocorretamente = ´´V´´ )as vlinformadocorretamente ´ +
´ from movimento a, respcaixa b ´+
´ where b.idcaixa = a.idcaixa ´ +
´ and a.dtmovimento between :pdtIn and :pdtFn ´+
´ and a.cxnaoinformado = ´´V´´ ´;
ParamByName(´pdtIn´).asDate := DataIn;
ParamByName(´pdtFn´).AsDate := DataFn;
Open;
end; Creio que esteja errado o select
GOSTEI 0
Emerson Nascimento
02/11/2008
esta nova condicao por data não deveria estar em todos os subselects?
GOSTEI 0
Emerson Nascimento
02/11/2008
não sei se entendi completamente sua necessidade, mas acredito que você pode deixar de utilizar todos esses subselects (que degradam a performance) e utilizar a função [i:605e84ac20]case[/i:605e84ac20] em conjunto com [i:605e84ac20]group by[/i:605e84ac20].
Sql.Text := ´ select a.idcaixa, b.nmcaixa, ´+ ´ sum(case when coalesce(a.vdnaofinalizada,´´F´´) = ´´V´´ ´+ ´ then 1 ´+ ´ else 0 end) as vdnaofinalizado, ´+ ´ sum(case when coalesce(a.cxnaoinformado,´´F´´) = ´´V´´ ´+ ´ then 1 ´+ ´ else 0 end) as CxNaoInformado, ´+ ´ sum(case when coalesce(a.inversaopgto,´´F´´) = ´´V´´ ´+ ´ then 1 ´+ ´ else 0 end) as InversaoPgto, ´ + ´ sum(case when coalesce(a.vdfinaldeumdiapoutro,´´F´´) = ´´V´´ ´+ ´ then 1 ´+ ´ else 0 end) as vdfinaldeumdiapoutro, ´ + ´ sum(case when coalesce(a.cxinfemdterrada,´´F´´) = ´´V´´ ´+ ´ then 1 ´+ ´ else 0 end) as cxinfemdterrada, ´ + ´ sum(case when coalesce(a.vlinformadocorretamente,´´F´´) = ´´V´´ ´+ ´ then 1 ´+ ´ else 0 end) as as vlinformadocorretamente ´ + ´ from movimento a, respcaixa b ´+ ´ where b.idcaixa = a.idcaixa ´ + ´ and a.dtmovimento between :pdtIn and :pdtFn ´+ ´ and a.cxnaoinformado = ´´V´´ ´+ ´ group by a.idcaixa, b.nmcaixa ´;
GOSTEI 0
Adriano_servitec
02/11/2008
não sei se entendi completamente sua necessidade, mas acredito que você pode deixar de utilizar todos esses subselects (que degradam a performance) e utilizar a função [i:5577551814]case[/i:5577551814] em conjunto com [i:5577551814]group by[/i:5577551814].
Sql.Text := ´ select a.idcaixa, b.nmcaixa, ´+ ´ sum(case when coalesce(a.vdnaofinalizada,´´F´´) = ´´V´´ ´+ ´ then 1 ´+ ´ else 0 end) as vdnaofinalizado, ´+ ´ sum(case when coalesce(a.cxnaoinformado,´´F´´) = ´´V´´ ´+ ´ then 1 ´+ ´ else 0 end) as CxNaoInformado, ´+ ´ sum(case when coalesce(a.inversaopgto,´´F´´) = ´´V´´ ´+ ´ then 1 ´+ ´ else 0 end) as InversaoPgto, ´ + ´ sum(case when coalesce(a.vdfinaldeumdiapoutro,´´F´´) = ´´V´´ ´+ ´ then 1 ´+ ´ else 0 end) as vdfinaldeumdiapoutro, ´ + ´ sum(case when coalesce(a.cxinfemdterrada,´´F´´) = ´´V´´ ´+ ´ then 1 ´+ ´ else 0 end) as cxinfemdterrada, ´ + ´ sum(case when coalesce(a.vlinformadocorretamente,´´F´´) = ´´V´´ ´+ ´ then 1 ´+ ´ else 0 end) as as vlinformadocorretamente ´ + ´ from movimento a, respcaixa b ´+ ´ where b.idcaixa = a.idcaixa ´ + ´ and a.dtmovimento between :pdtIn and :pdtFn ´+ ´ and a.cxnaoinformado = ´´V´´ ´+ ´ group by a.idcaixa, b.nmcaixa ´;
Olá [b:5577551814]emerson.en[/b:5577551814], testei este select que você postou, pareçe que esta mostrando o resultado certo, não testei bem ainda.
Vou tentar mostrar como esta na tabela (vou encurtar os campos somente para mostrar como esta)
ID----data---------campo1----campo2-----campo3-----campo4 2-----01.11.2008-----V--------------------------------------------- 2-----01.11.2008-----V-----------V-------------------------V-----
Então o select creio eu que não vai precisar desta condição aqui em destaque abaixo
´ from movimento a, respcaixa b ´+
´ where b.idcaixa = a.idcaixa ´ +
´ and a.dtmovimento between :pdtIn and :pdtFn ´+
[color=blue:5577551814][i:5577551814]-- ´ and a.cxnaoinformado = ´´V´´ ´+[/i:5577551814][/color:5577551814]
´ group by a.idcaixa, b.nmcaixa ´;
Vou fazer mais uns testes, pra ver se esta correto os valores, mais a principio pareçe que sim.
Outra duvida também amigo.
mas acredito que você pode deixar de utilizar todos esses subselects (que degradam a performance) e utilizar a função case em conjunto com group by.
Aqui o que você quis dizer é que com os subselects ficaria mais lento o SQL?
Obrigado por me ajudar amigo.
GOSTEI 0
Adriano_servitec
02/11/2008
Ola Emerson, vendo aqui nos testes percebi que esta agrupando por ID, e eu preciso que cada dia tenha o seu resultado
Então são datas diferente e mesmo assim agrupa num só sele
ID----data---------campo1----campo2-----campo3-----campo4
2-----01.11.2008-----V---------------------------------------------
2-----02.11.2008-----V-----------V-------------------------V-----
Então são datas diferente e mesmo assim agrupa num só sele
GOSTEI 0
Emerson Nascimento
02/11/2008
selecione a data e a coloque no group by também.
GOSTEI 0
Adriano_servitec
02/11/2008
selecione a data e a coloque no group by também.
Verdade, nem tinha pensado nisso. Agora pareçe que está certo.Mais uma vez obrigado.
GOSTEI 0
Adriano_servitec
02/11/2008
Surgiu mais um problema, preciso montar o select dos responsaveis pelo caixa que mais erram em ordem dos que mais erram do maior para o menor.
Pensei num order by DESC, mais como seria neste select?
Não estou sabendo como montar este SQL
Grato pela ajuda
Adriano.
Pensei num order by DESC, mais como seria neste select?
var
DataIn, DataFn : TDate;
begin
inherited;
if RadioButton2.Checked = True then
begin
{Passando as datas para variaveis}
DataIn := StrToDate(MaskEdit1.Text);
DataFn := StrToDate(MaskEdit2.Text);
with IBQListCaixa do
begin
Close;
Sql.Clear;
Sql.Text := ´ select a.idcaixa, b.nmcaixa, c.nmloja, ´+
´ sum(case when coalesce(a.vdnaofinalizada,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as vdnaofinalizado, ´+
´ sum(case when coalesce(a.cxnaoinformado,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as CxNaoInformado, ´+
´ sum(case when coalesce(a.inversaopgto,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as InversaoPgto, ´ +
´ sum(case when coalesce(a.vdfinaldeumdiapoutro,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as vdfinaldeumdiapoutro, ´ +
´ sum(case when coalesce(a.cxinfemdterrada,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as cxinfemdterrada, ´ +
´ sum(case when coalesce(a.vlinformadocorretamente,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as vlinformadocorretamente, ´ +
´ sum(case when coalesce(a.sangriaincorreta,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as sangriaincorreta, ´ +
´ sum(case when coalesce(a.outrostperros,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as outrostperros ´ +
´ from movimento a, respcaixa b, lojas c ´+
´ where b.idcaixa = a.idcaixa ´ +
´ and c.id_loja = b.idloja ´+
´ and a.dtmovimento between :pdtIn and :pdtFn ´+
´ group by a.idcaixa, b.nmcaixa, c.nmloja ´;//+
// ´ order by vdnaofinalizada, desc ´;
ParamByName(´pdtIn´).asDate := DataIn;
ParamByName(´pdtFn´).AsDate := DataFn;
Open;
end;Não estou sabendo como montar este SQL
Grato pela ajuda
Adriano.
GOSTEI 0
Emerson Nascimento
02/11/2008
e como você identifica quem errou mais? apenas por um campo ou a soma desses campos?
GOSTEI 0
Adriano_servitec
02/11/2008
e como você identifica quem errou mais? apenas por um campo ou a soma desses campos?
Eu acho que tem que ser a soma de todos os campos, pois fiz assim e não deu certovar
DataIn, DataFn : TDate;
begin
inherited;
if RadioButton2.Checked = True then
begin
{Passando as datas para variaveis}
DataIn := StrToDate(MaskEdit1.Text);
DataFn := StrToDate(MaskEdit2.Text);
with IBQListCaixa do
begin
Close;
Sql.Clear;
Sql.Text := ´ select a.idcaixa, b.nmcaixa, c.nmloja, ´+
´ sum(case when coalesce(a.vdnaofinalizada,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as vdnaofinalizado, ´+
´ sum(case when coalesce(a.cxnaoinformado,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as CxNaoInformado, ´+
´ sum(case when coalesce(a.inversaopgto,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as InversaoPgto, ´ +
´ sum(case when coalesce(a.vdfinaldeumdiapoutro,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as vdfinaldeumdiapoutro, ´ +
´ sum(case when coalesce(a.cxinfemdterrada,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as cxinfemdterrada, ´ +
´ sum(case when coalesce(a.vlinformadocorretamente,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as vlinformadocorretamente, ´ +
´ sum(case when coalesce(a.sangriaincorreta,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as sangriaincorreta, ´ +
´ sum(case when coalesce(a.outrostperros,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as outrostperros ´ +
´ from movimento a, respcaixa b, lojas c ´+
´ where b.idcaixa = a.idcaixa ´ +
´ and c.id_loja = b.idloja ´+
´ and a.dtmovimento between :pdtIn and :pdtFn ´+
´ group by a.idcaixa, b.nmcaixa, c.nmloja ´+
´ order by 4,5,6,7,8,9,10,11 desc ´;
ParamByName(´pdtIn´).asDate := DataIn;
ParamByName(´pdtFn´).AsDate := DataFn;
Open;
end;
end;GOSTEI 0
Adriano_servitec
02/11/2008
Preciso fazer a soma mesmo pra saber quem errou mais dentro daqueles campos.
Sobe...
Sobe...
GOSTEI 0
Emerson Nascimento
02/11/2008
a forma que eu achei foi refazer a soma...
var
DataIn, DataFn : TDate;
begin
inherited;
if RadioButton2.Checked = True then
begin
{Passando as datas para variaveis}
DataIn := StrToDate(MaskEdit1.Text);
DataFn := StrToDate(MaskEdit2.Text);
with IBQListCaixa do
begin
Close;
Sql.Clear;
Sql.Text := ´ select a.idcaixa, b.nmcaixa, c.nmloja, ´+
´ sum(case when coalesce(a.vdnaofinalizada,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as vdnaofinalizado, ´+
´ sum(case when coalesce(a.cxnaoinformado,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as CxNaoInformado, ´+
´ sum(case when coalesce(a.inversaopgto,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as InversaoPgto, ´ +
´ sum(case when coalesce(a.vdfinaldeumdiapoutro,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as vdfinaldeumdiapoutro, ´ +
´ sum(case when coalesce(a.cxinfemdterrada,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as cxinfemdterrada, ´ +
´ sum(case when coalesce(a.vlinformadocorretamente,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as vlinformadocorretamente, ´ +
´ sum(case when coalesce(a.sangriaincorreta,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as sangriaincorreta, ´ +
´ sum(case when coalesce(a.outrostperros,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as outrostperros, ´ +
//*** total de erros. esse será o campo usado no order by ***//
´ sum(case when coalesce(a.vdnaofinalizada,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) + ´+
´ sum(case when coalesce(a.cxnaoinformado,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) + ´+
´ sum(case when coalesce(a.inversaopgto,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) + ´ +
´ sum(case when coalesce(a.vdfinaldeumdiapoutro,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) + ´ +
´ sum(case when coalesce(a.cxinfemdterrada,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) + ´ +
´ sum(case when coalesce(a.vlinformadocorretamente,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) + ´ +
´ sum(case when coalesce(a.sangriaincorreta,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) + ´ +
´ sum(case when coalesce(a.outrostperros,´´F´´) = ´´V´´ ´+
´ then 1 ´+
´ else 0 end) as total_de_erros ´ +
´ from movimento a, respcaixa b, lojas c ´+
´ where b.idcaixa = a.idcaixa ´ +
´ and c.id_loja = b.idloja ´+
´ and a.dtmovimento between :pdtIn and :pdtFn ´+
´ group by a.idcaixa, b.nmcaixa, c.nmloja ´+
´ order by 12 desc ´;
ParamByName(´pdtIn´).asDate := DataIn;
ParamByName(´pdtFn´).AsDate := DataFn;
Open;
end;
end;GOSTEI 0
Adriano_servitec
02/11/2008
Olá Emerson, ja melhorou bastante, esta ordenando pela soma, só mais uma duvida.
Tem como eu jogar o total, por nome deste select em um novo campo também?
Tipo assim
fulano---total erros 10
ciclano--total erros 8
beltrano---total erros 5
Isso tudo no mesmo select
É que a ideia seria tirar um relatorio num determinado período e em baixo neste relatorio um total
Grato
Adriano
Tem como eu jogar o total, por nome deste select em um novo campo também?
Tipo assim
fulano---total erros 10
ciclano--total erros 8
beltrano---total erros 5
Isso tudo no mesmo select
É que a ideia seria tirar um relatorio num determinado período e em baixo neste relatorio um total
Grato
Adriano
GOSTEI 0
Adriano_servitec
02/11/2008
Olá Emerson, ja melhorou bastante, esta ordenando pela soma, só mais uma duvida.
Tem como eu jogar o total, por nome deste select em um novo campo também?
Tipo assim
fulano---total erros 10
ciclano--total erros 8
beltrano---total erros 5
Isso tudo no mesmo select
É que a ideia seria tirar um relatorio num determinado período e em baixo neste relatorio um total
Grato
Adriano
Será que tem como gerar um total geral neste select?Sobe...
GOSTEI 0
Adriano_servitec
02/11/2008
Pessoal, alguém sabe se pelo menos teria alguma forma de somar o total de cada um? Independente de ser no mesmo select? Ou seja em um outro select, não estou sabendo motar esta soma.
GOSTEI 0
Adriano_servitec
02/11/2008
Consegui resolver, valeu Emerson, obrigado pela ajuda amigo.
GOSTEI 0