O tio Iron está ficando meio velho…tô apanhando de uma query(Oracle 10g) super simples aqui!
Seguinte:Tenho um campo(cliente_x_hora) na qual eu conto as ocorrencias desse campo e exibo graficamente no JFreeChart.Até aí tudo bem, antes de montar a query, eu seleciono até 3 itens(número do intervalo,valor do intervalo e valor mínimo) e aperto o botão que gerará a query.(O menor valor possível é 0 e o maior é 34299.2 nesse campo-que é NUMERIC-, com um total de 87687 registros).
Devo estar velho no SQL(até copiei de outro post), mas quando eu seleciono apenas número do intervalo(=5) e valor do Intervalo(=1000.0), eu obtenho a seguinte imagem:
http://img585.imageshack.us/img585/5025/querycom5intervalo1000v.png
Para a seguinte query:
SELECT INTERVAL, COUNT(*) TOTAL FROM (
SELECT CASE WHEN CLIENTE_X_HORA>0 AND CLIENTE_X_HORA<=1000.00 THEN '0<CLIENTE_X_HORA><=1000.00'
WHEN CLIENTE_X_HORA>1000.00 AND CLIENTE_X_HORA<=2000.00 THEN '1000.00<CLIENTE_X_HORA><=2000.00'
WHEN CLIENTE_X_HORA>2000.00 AND CLIENTE_X_HORA<=3000.00 THEN '2000.00<CLIENTE_X_HORA><=3000.00'
WHEN CLIENTE_X_HORA>3000.00 AND CLIENTE_X_HORA<=4000.00 THEN '3000.00<CLIENTE_X_HORA><=4000.00'
ELSE '4000.00<CLIENTE_X_HORA' END INTERVAL, CLIENTE_X_HORA FROM SGD_CAUSA) GROUP BY INTERVAL ORDER BY TOTAL
Quando eu seleciono também o valor inicial(=2000.0), eu obtenho essa imagem:
http://img40.imageshack.us/img40/5025/querycom5intervalo1000v.png
Para a seguinte query:
SELECT INTERVAL, COUNT(*) TOTAL FROM (
SELECT CASE WHEN CLIENTE_X_HORA>2000.00 AND CLIENTE_X_HORA<=3000.00 THEN '2000.00<CLIENTE_X_HORA><=3000.00'
WHEN CLIENTE_X_HORA>3000.00 AND CLIENTE_X_HORA<=4000.00 THEN '3000.00<CLIENTE_X_HORA><=4000.00'
WHEN CLIENTE_X_HORA>4000.00 AND CLIENTE_X_HORA<=5000.00 THEN '4000.00<CLIENTE_X_HORA><=5000.00'
WHEN CLIENTE_X_HORA>5000.00 AND CLIENTE_X_HORA<=6000.00 THEN '5000.00<CLIENTE_X_HORA><=6000.00'
ELSE '6000.00<CLIENTE_X_HORA' END INTERVAL, CLIENTE_X_HORA FROM SGD_CAUSA) GROUP BY INTERVAL ORDER BY TOTAL
Quando eu aumentei a frequencia, o resultado de >6000 gerou uma barra de 86049, um erro claro, pois o número de ocorrências é muito menor acima desse valor.Onde está o erro nessa query?
Eu acho que aconteceu o seguinte: a cláusula CLIENTE_X_HORA>0 AND CLIENTE_X_HORA<=1000.00 da primeira query retornou mais valores, e como ela não está na segunda query, os resultados dela cairam no ELSE , que chegou nos 86049.
Boaglio, existe um meio de contornar isso?Pensei que ao por 6000.00<CLIENTE_X_HORA, eu só cairia no que fosse maior do esse valor… eu tenho que explicitar de algo forma?Principalmente pq essa query é dinamicamente montada, depende do que o usuário está selecionando, acho que eu tenho que dizer ao Oracle que eu não quero os valores menores que o 2000(ou qualquer valor mínimo que o user aceite).Como eu monto essa query?
>
Tentei fazer um select sem ELSE, assim:
valor_final="WHEN "+campo_selecionado+">"+valorMaximo+" THEN '"+valorMaximo+"<"+campo_selecionado+"'";
Que gera um final de query assim:WHEN CLIENTE_X_HORA>6000.00 THEN ‘6000.00<CLIENTE_X_HORA’ END INTERVAL ao invés do trecho com ELSE, mas dá um:
java.lang.IllegalArgumentException: Null ‘key’ argument.
Tem um modo prático de contornar isso, o google não está ajudando muito , não? 
>
Corrigi, para evitar os nulos:
SELECT INTERVAL, COUNT(*) TOTAL FROM (SELECT CASE WHEN CLIENTE_X_HORA>2000.00 AND CLIENTE_X_HORA<=3000.00 THEN '2000.00<CLIENTE_X_HORA><=3000.00' WHEN CLIENTE_X_HORA>3000.00 AND CLIENTE_X_HORA<=4000.00 THEN '3000.00<CLIENTE_X_HORA><=4000.00' WHEN CLIENTE_X_HORA>4000.00 AND CLIENTE_X_HORA<=5000.00 THEN '4000.00<CLIENTE_X_HORA><=5000.00' WHEN CLIENTE_X_HORA>5000.00 AND CLIENTE_X_HORA<=6000.00 THEN '5000.00<CLIENTE_X_HORA><=6000.00' WHEN CLIENTE_X_HORA>6000.00 THEN '6000.00<CLIENTE_X_HORA' END INTERVAL, CLIENTE_X_HORA FROM SGD_CAUSA) GROUP BY INTERVAL HAVING INTERVAL IS NOT NULL ORDER BY TOTAL[/code]
Mas me dá um gráfico:
http://img853.imageshack.us/img853/5144/with5and1000with2000ini.png
O que é errado, pois os valores maiores que 4000 dão muito mais do que estão sendo exibidos.Sem valor inicial(valor inicial começando de 0), a query é:
[code]SELECT INTERVAL, COUNT(*) TOTAL FROM (SELECT CASE WHEN CLIENTE_X_HORA>0 AND CLIENTE_X_HORA<=1000.00 THEN '0<CLIENTE_X_HORA><=1000.00' WHEN CLIENTE_X_HORA>1000.00 AND CLIENTE_X_HORA<=2000.00 THEN '1000.00<CLIENTE_X_HORA><=2000.00' WHEN CLIENTE_X_HORA>2000.00 AND CLIENTE_X_HORA<=3000.00 THEN '2000.00<CLIENTE_X_HORA><=3000.00' WHEN CLIENTE_X_HORA>3000.00 AND CLIENTE_X_HORA<=4000.00 THEN '3000.00<CLIENTE_X_HORA><=4000.00' ELSE '4000.00<CLIENTE_X_HORA' END INTERVAL, CLIENTE_X_HORA FROM SGD_CAUSA) GROUP BY INTERVAL HAVING INTERVAL IS NOT NULL ORDER BY TOTAL
E o gráfico: http://img109.imageshack.us/img109/1261/with5and1000with0initia.png
O que é condizente com os dados disponíveis.Se alguém tiver alguma idéia eu aceito.
>
Tentando forçar um resultado com o inicial WHERE>2000, o que me dá uma query assim:
SELECT INTERVAL, COUNT(*) TOTAL FROM (SELECT CASE WHEN CLIENTE_X_HORA>2000.00 AND CLIENTE_X_HORA<=3000.00 THEN '2000.00<CLIENTE_X_HORA><=3000.00' WHEN CLIENTE_X_HORA>3000.00 AND CLIENTE_X_HORA<=4000.00 THEN '3000.00<CLIENTE_X_HORA><=4000.00' WHEN CLIENTE_X_HORA>4000.00 AND CLIENTE_X_HORA<=5000.00 THEN '4000.00<CLIENTE_X_HORA><=5000.00' WHEN CLIENTE_X_HORA>5000.00 AND CLIENTE_X_HORA<=6000.00 THEN '5000.00<CLIENTE_X_HORA><=6000.00' WHEN CLIENTE_X_HORA>6000.00 THEN '6000.00<CLIENTE_X_HORA' END INTERVAL, CLIENTE_X_HORA FROM SGD_CAUSA WHERE CLIENTE_X_HORA>2000.00) GROUP BY INTERVAL HAVING INTERVAL IS NOT NULL ORDER BY TOTAL
Mas me dá um resultado meio bizarro:

Os valores estão abaixo do que deveriam, só comparar quando o valor inicial é 0(repare nos valores acima de 4000):

Sempre aprendendo… nunca passou pela minha cabeça que o ELSE pega até negativos(em bom português: tudo e mais alguma coisa!).Graças ao Fernando Boaglio cheguei a resposta certa:
Quando há um intervalo escolhido pelo usuário a resposta é:
SELECT INTERVAL, COUNT(*) TOTAL FROM (SELECT CASE WHEN CLIENTE_X_HORA>2000.00 AND CLIENTE_X_HORA<=3000.00 THEN '2000.00<CLIENTE_X_HORA><=3000.00' WHEN CLIENTE_X_HORA>3000.00 AND CLIENTE_X_HORA<=4000.00 THEN '3000.00<CLIENTE_X_HORA><=4000.00' WHEN CLIENTE_X_HORA>4000.00 AND CLIENTE_X_HORA<=5000.00 THEN '4000.00<CLIENTE_X_HORA><=5000.00' WHEN CLIENTE_X_HORA>5000.00 AND CLIENTE_X_HORA<=6000.00 THEN '5000.00<CLIENTE_X_HORA><=6000.00' WHEN CLIENTE_X_HORA>6000.00 THEN '6000.00<CLIENTE_X_HORA' END INTERVAL, CLIENTE_X_HORA FROM SGD_CAUSA WHERE CLIENTE_X_HORA>2000.00) GROUP BY INTERVAL HAVING INTERVAL IS NOT NULL ORDER BY TOTAL
Quando não há(o valor começa em ZERO):
SELECT INTERVAL, COUNT(*) TOTAL FROM (SELECT CASE WHEN CLIENTE_X_HORA>0 AND CLIENTE_X_HORA<=1000.00 THEN '0<CLIENTE_X_HORA><=1000.00' WHEN CLIENTE_X_HORA>1000.00 AND CLIENTE_X_HORA<=2000.00 THEN '1000.00<CLIENTE_X_HORA><=2000.00' WHEN CLIENTE_X_HORA>2000.00 AND CLIENTE_X_HORA<=3000.00 THEN '2000.00<CLIENTE_X_HORA><=3000.00' WHEN CLIENTE_X_HORA>3000.00 AND CLIENTE_X_HORA<=4000.00 THEN '3000.00<CLIENTE_X_HORA><=4000.00' WHEN CLIENTE_X_HORA>4000.00 THEN '4000.00<CLIENTE_X_HORA' END INTERVAL, CLIENTE_X_HORA FROM SGD_CAUSA) GROUP BY INTERVAL HAVING INTERVAL IS NOT NULL ORDER BY TOTAL
>