Ajuda con instrucao SQL

Delphi

23/01/2006

SELECT * from ARQ_HIST a1 WHERE PAGA is null and  
(venc between current_date -140 and current_date -5) and not exists 
(select * from arq_hist a2 where (paga is null) and 
(a2.inscricao = a1.inscricao) and (venc < current_date -140))
and exists (select * from arq_nome a3 where 
(a3.inscricao = a1.inscricao) and (fale is null))


O que isso faz: Seleciona todos os registros que estao devendo de 140 dias até a data de 5 dias atras. Nas duas ultimas linhas eu queria que ele
filtrasse todos onde o campo FALE é nulo.
Mas quando eu rodo a pesquisa ele me tras os registros e inclui tbem os do campo FALE nao nulos...

Alguma dica ?


Geisonc

Geisonc

Curtidas 0

Respostas

Geisonc

Geisonc

23/01/2006

ohem que estranho... eu fiz deste modo e deu certo....

         a:=´SELECT * from ARQ_HIST a1 WHERE PAGA is null and venc between current_date -140 and current_date -5 and not exists´;
         b:=´(select * from arq_hist a2 where paga is null and a2.inscricao = a1.inscricao and venc < current_date -140) and exists´;
         c:=´(select * from arq_nome a3 where a1.inscricao = a3.inscricao and fale is not null) and exists´;
         d:=´(select * from arq_prin a4 where a1.inscricao = a4.inscricao and telefone is not null)´;


Agora se eu quero a mesma consulta porem com o campo FALE nulo,seria só tirar o [b:473127296f]not null [/b:473127296f]e colocar apenas [b:473127296f]null[/b:473127296f] no lugar..

(select * from arq_nome a3 where a1.inscricao = a3.inscricao and fale is null) and exists´...



ele nao filtra... mostra independente de ter dados ou nao neste campo.


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

23/01/2006

você precisa certificar-se se o campo está nulo ou simplesmente vazio, que são coisas diferentes.
veja se assim funciona:

SELECT
  a1.*
from
  ARQ_HIST a1
WHERE
  (a1.PAGA is null)
  and (a1.venc between current_date-140 and current_date-5)
  and not exists(select
                   *
                 from
                   arq_hist a2
                 where
                   (a2.paga is null)
                   and (a2.inscricao = a1.inscricao)
                   and (a2.venc < current_date -140))
  and exists (select
                *
              from
                arq_nome a3
              where
                (a3.inscricao = a1.inscricao)
                and (coalesce(fale,´´) = ´´))

como não foi informado o banco de dados, fiz a instrução para o FB.
no caso de SQL Server, troque coalesce() por isnull().
como também não informado o tipo do campo FALE, supus que seja alfanumérico


GOSTEI 0
Geisonc

Geisonc

23/01/2006

Ola colega !

Uso o Firebird.
O campo FALE é do tipo DATA.
Nao conheco o [b:197ce649ac]coalesce[/b:197ce649ac] como ele funciona ?.

Obrigado pela ajuda !


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

23/01/2006

coalesce() serve para retornar um valor alternativo caso a avaliação do parâmetro ´anterior´ seja nula.

por exemplo: imagine que você tem uma tabela de funcionário onde há os campos NOME, TELEFONE_RES e TELEFONE_CEL, com os seguintes registros:
NOME       TELEFONE_RES  TELEFONE_CEL
----------------------------------
JOAO       6121-3214     8998-7887
JOSE       Null          9696-9898
ANTONIO    Null          Null
MARIA      Null          9595-5454
SILVIA     Null          Null
PEDRO      6554-5445     Null


a instrução
select
  nome,
  coalesce(telefone_res,telefone_cel,´Não tem tel.´)
from funcionarios

resultaria em:
JOAO       6121-3214
JOSE       9696-9898
ANTONIO    Não tem tel.
MARIA      9595-5454
SILVIA     Não tem tel.
PEDRO      6554-5445



GOSTEI 0
Geisonc

Geisonc

23/01/2006

Bom pessoal, eu descobri o porque o filtro dava errado. como eu nao fiz este banco, nao sabia que era assim que funcionava,. mas a estrutura da tabela eh resumidamente assim...


| INSCRICAO | GRUPO  | SQUENCIA |  FALE  |
|      100  |  LON   |     01   |        | 
|      101  |  LON   |     01   |        |
|      100  |  LON   |     02   | 10/05  |



(FALE = FALECIMENTO)

Cada numero de inscricao é igual a um cliente. [b:18fc938d9a]MAS[/b:18fc938d9a] cada cliente tem N [b:18fc938d9a] DEPENDENTES [/b:18fc938d9a]

Entao uma inscricao pode ter varios dependendes. E se por exemplo eu pedia pra fazer uma pesquisa de todos os que o campo FALE era null, neste caso ele traria a INSCRICAO 100, pq há um registro nulo, embora tenha com o mesmo registro mas em outra sequencia um registro FALE em NOT NULL.

Mas agora como eu faco a pesquisa sendo que uma inscricao tem varios dependentes (na mesma tabela) ? e por exemplo, se eu quiser selecionar todos os FALE NULOS, e se um dependente ja tiver falecido, ele nao podera mostrar akela inscricao...
É complicado ou sou eu que to complicando demais ?


Obrigado a todos !!!


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

23/01/2006

tente assim:
SELECT 
  a1.* 
from 
  ARQ_HIST a1 
WHERE 
  (a1.PAGA is null) 
  and (a1.venc between current_date-140 and current_date-5) 
  and not exists(select 
                   * 
                 from 
                   arq_hist a2 
                 where 
                   (a2.paga is null) 
                   and (a2.inscricao = a1.inscricao) 
                   and (a2.venc < current_date -140)) 
  and not a1.inscricao in
                (select 
                  a3.inscricao
                from 
                  arq_nome a3 
                where 
                  fale is null)



GOSTEI 0
Geisonc

Geisonc

23/01/2006

nao mostrou nenhum dado... mas vou estuda-la para ver o que precisa ser alterado ! Vc usou um [b] IN [b] na instrucao.. interessante !

as instrucoes que eu fazia em SQL eram todas simples, insercao, edicao.. agora eu to apanhando um pouco....

mas to aprendendo... é o que interessa !!



Obrigado pela ajuda,


GOSTEI 0
Geisonc

Geisonc

23/01/2006

Bom pessoal, realmente nao estou conseguindo agora, se a inscricao fosse em uma tabela e a Sequencia em outra, daria certo, mas desse jeito nao to conseguindo....

emerson.en, mais alguma dica que possa me passar ?

Muito Obrigado a todos.


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

23/01/2006

tente assim:
SELECT
  a1.*
from
  ARQ_HIST a1
WHERE
  (a1.PAGA is null) and
  (a1.venc between current_date -140 and current_date -5) and
  not a1.inscricao in (select
                         a2.inscricao
                       from
                         arq_hist a2
                       where
                         (a2.inscricao = a1.inscricao) and
                         ( (venc < current_date -140) or
                           (fale is null)
                         )
                      )


se não aparecer nada, talvez esteja no mesmo caso da explicação que você deu anteriormente:
uma inscrição pode ter registros com FALE=NULL e FALE<>NULL
ou pode ter também registros com (VENC < CURRENT_DATE -140) e (VENC >= CURRENT_DATE -140). nesse caso, nada será mostrado.


GOSTEI 0
Geisonc

Geisonc

23/01/2006

mas no caso do codigo acima, FALE esta sendo como da mesma tabela, porem o FALE é da tabela arq_nome...

Suponhamos assim: Esquecemos o periodo de datas para filtro, selecionamos apenas os registros que tenham o campo FALE null ( é null mesmo, verifiquei no IBConsole), como ficaria para filtrar o campo inscricao quando fale é nulo e todos os seus dependentes (squencia) tbem sejam ? pq se um dependente (squencia) nao estiver nulo, ele já anula aquela inscricao...

Eu to me explicando direito ?


GOSTEI 0
Geisonc

Geisonc

23/01/2006

bom... fiz assim alterando só a tabela no exemplo q vc deu...

SELECT
  a1.*
from
  ARQ_HIST a1
WHERE
  (a1.PAGA is null) and
  (a1.venc between current_date -140 and current_date -5) and
  not a1.inscricao in (select
                         a2.inscricao
                       from
                         arq_hist a2
                       where
                         (a2.inscricao = a1.inscricao) and
                         ( (venc < current_date -140) or not exists
                         (select * from arq_nome where
                           (fale is null))
                         )
                      )


Aparentemente nao ta mostrando os FALE NOT NULL, agora vou fazer uns testes mais rigorosos e posto aki caso de errado !!

Muito Obrigado mais uma vez.


GOSTEI 0
Geisonc

Geisonc

23/01/2006

ta mostrando os not null tbem pelo motivo de uma insricao ter varios dependentes. um exemplo do resultado da consulta acima foi desta inscricao: (foram mostradas varias inscricoes coloquei apenas uma que nao poderia estar mostrando)...


| Inscricao  | Nome          | Squencia       |       FALE

    4933     | Maria         |    1           |   null
    4933     | Joao          |    2           |  10/01/2005
    4933     | Marcos        |    3           |  null
    4933     | Geison        |    4           |  null
    4933     | Roberval      |    5           |  null
    4933     | Ataide        |    6           |  null


No caso, ele mostrou essa inscricao como resultado pq dentro da inscricao 4933 a 6 dependetes, e apenas um tem o campo fale nao nulo, entao ele mostrou os outros 5 que tem o campo FALE null,,, mas quando algum dependete de alguma inscricao tiver o campo fale nao nulo, já nao podera ser mostrado no relatorio.
[/code]


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

23/01/2006

com essa instrução, qual é o retorno?
SELECT 
  a1.* 
from 
  ARQ_HIST a1 
WHERE 
  (a1.PAGA is null) and 
  (a1.venc between current_date -140 and current_date -5) and 
  not a1.inscricao in (select 
                         a2.inscricao 
                       from 
                         arq_hist a2 
                       where 
                         (a2.inscricao = a1.inscricao) and 
                         ( (a2.venc < current_date -140) or 
                           (a2.fale is null) 
                         ) 
                      )



GOSTEI 0
Thomaz_prg

Thomaz_prg

23/01/2006

Pessoal, como dizem, ´peguei o bonde andando´, mas se a intenção é mostrar todos os que estão com data de vencimento entre 140 dias atrás, até os 5dias atrás, quando o campo Fale for nulo, não seria só isso??


SELECT  * 
FROM ARQ_HIST A1
WHERE 
  (PAGA IS NULL) AND
  (venc between current_date -145 and current_date -5) AND
  (FALE IS NULL) 


Notem que coloquei Current_Date - 145, pois se entendi bem, seria os que estariam vencidos a 140 dias até a data de 5 dias atrás. Tente aí pra ver se funciona.


GOSTEI 0
Geisonc

Geisonc

23/01/2006

emerson.en , da um erro pois nao existe o campo FALE na tabela arq_hist e sim na arq_nome.
As duas tabelas sao assim:

ARQ_HIST

| Inscricao  |  Grupo  |  Venc       |  Paga       |
|  100       |  IBI    | 1/01/2006   | 01/01/2006  |
|   101      |  LON    | 12/01/2006  |  12/01/2006 |
|   102      |  CUR    | 10/01/2006  | 11/01/2006  |


agora a arq_nome
| Inscricao  |  squencia  |  Nome    |  Fale       |
|  100       |  1         | Geison   | 01/01/2006   |
|   101      |  1         | Marcos   | 12/01/2006   |
|   102      |  1         | Ruy      | 11/01/2006   |
|   102      |  2         | Ruy      | null         |
|   102      |  3         | Ruy      | null         |


thomaz_prg .
seria perfeito o codigo se nao tivesse que procurar o FALE null, pois se eu quer consultar qual o cliente que nao tem nenhum falecimento na familia ele procura na inscricao do cliente, mas na inscricao do cliente pode ter varios parentes, mas com a mesma inscricao o que vai mudar eh o numero de sequencia. no exemplo da tabela ai em cima, a inscricao 102 tem 2 registros nulos e um com falecimento. quando peco pra fazer a consulta ele ta trazendo os 2 registros nulos, mas como akela inscricao já tem um falecimento, nao poderia estar constando no relatorio.


GOSTEI 0
Thomaz_prg

Thomaz_prg

23/01/2006

Se for para constar apenas os que não tem falecimento no cliente, ou seja, nos de sequencia = 001, daria pra fazer assim:

SELECT  * 
FROM ARQ_HIST A1 
WHERE 
  (PAGA IS NULL) AND 
  (venc between current_date -145 and current_date -5) AND 
  EXISTS(SELECT A2.INSCRICAO FROM ARQ_HIST A2 
              WHERE 
                   (A2.SEQUENCIA = 01) AND 
                   (A2.INSCRICAO = A1.INSCRICAO) AND
                   (A2.FALE IS NULL)
  )


Se for para mostrar os que não possuem falecimento nenhum, nem do cliente, nem de algum dos dependentes, daria pra ser assim:

SELECT  * 
FROM ARQ_HIST A1 
WHERE 
  (PAGA IS NULL) AND 
  (venc between current_date -145 and current_date -5) AND 
  EXISTS(SELECT A2.INSCRICAO FROM ARQ_HIST A2 
              WHERE 
                   (A2.INSCRICAO = A1.INSCRICAO) AND
                   (A2.FALE IS NULL)
  )



GOSTEI 0
Emerson Nascimento

Emerson Nascimento

23/01/2006

tente assim:
SELECT 
  a1.* 
from 
  ARQ_HIST a1 
WHERE 
  (a1.PAGA is null) and 
  (a1.venc between current_date -140 and current_date -5) and 
  not a1.inscricao in (select
                         inscricao
                       from
                         arq_nome
                       where 
                         fale is null
                      )

eu não havia percebido que o campo FALE estava em outra tabela... :?


GOSTEI 0
Geisonc

Geisonc

23/01/2006

mas o campo FALE é de outra tabela...no caso da sua 2ª exemplo, que seria o certo para o que eu preciso, o campo FALE esta se referindo ao a2, que por sinal é da tabela arq_hist, o certo seria na tabela arq_nome...

fiz esta alteracao mas ele ainda mostra os campos que nao sao nulos..

SELECT  *
FROM ARQ_HIST A1
WHERE
  (PAGA IS NULL) AND
  (venc between current_date -145 and current_date -5) AND
  EXISTS(SELECT A2.INSCRICAO FROM ARQ_HIST A2
              WHERE
                   (A2.INSCRICAO = A1.INSCRICAO) AND exists
                   (select * from arq_nome a3 where
                   (A3.FALE IS NULL)))



GOSTEI 0
Emerson Nascimento

Emerson Nascimento

23/01/2006

ou ainda:
SELECT 
  a1.* 
from 
  ARQ_HIST a1 
WHERE 
  (a1.PAGA is null) and 
  (a1.venc between current_date -140 and current_date -5) and 
  not a1.inscricao in (select
                         arqn.inscricao
                       from
                         arq_nome arqn
                       where
                         (arqn.inscricao = a1.inscricao) and
                         (arqn.fale is null)
                      )



GOSTEI 0
Emerson Nascimento

Emerson Nascimento

23/01/2006

tentou dessa outra forma?


GOSTEI 0
Geisonc

Geisonc

23/01/2006

Fiz sim, mas ele mostra 14 registros com óbito de inscricoes variadas;


GOSTEI 0
Geisonc

Geisonc

23/01/2006

Um algoritimo mal feito para ser feito em paradox seria +- assim...

Pega a primeira inscricao, conta quandos dependentes tem, e vai para o primeiro dependente...

enquanto nao chegar o ultimo dependente ele verifica
periodo de vencimento é tal, e se o campo fale é nulo
se o campo fale é nulo ele vai para o proximo dependente
se nao ele para e descarta a inscricao

se todos os dependentes forem nulo, vai para o relatorio...


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

23/01/2006

tem como vc enviar o script para criar e popular essas duas tabelas? assim dá pra fazer testes mais confiáveis...


GOSTEI 0
Geisonc

Geisonc

23/01/2006

Tabela arq_hist

/* Table: ARQ_HIST, Owner: SYSDBA */

CREATE TABLE "ARQ_HIST" 
(
  "GRUPO"VARCHAR(5),
  "REFER"VARCHAR(5),
  "TIPODEB"VARCHAR(3),
  "VALOR"NUMERIC(5, 2),
  "VENC"DATE,
  "PAGA"DATE,
  "LANC"VARCHAR(1),
  "VALOR_PAGO"NUMERIC(12, 0),
  "USUARIO"VARCHAR(10),
  "VENCSEQ"DATE,
  "SEQ_LOC"NUMERIC(9, 0),
  "VALOR_GAR"NUMERIC(6, 0),
  "ORDEM"NUMERIC(4, 0),
  "CODCOBR"VARCHAR(3),
  "CANC_ALTZ"VARCHAR(1),
  "DATA"DATE,
  "EXPORTA"DATE,
  "DATAAUX"DATE,
  "VALOR_AUX"NUMERIC(12, 0),
  "SEQUENCIA"INTEGER,
  "INSCRICAO"FLOAT,
  "USUARIOSAF"VARCHAR(30),
  "EMUSO"VARCHAR(1),
  "HC"VARCHAR(1)
);


tabela arq_prin


CREATE TABLE "ARQ_PRIN" 
(
  "INSCRICAO"NUMERIC(9, 0),
  "CONTROLE"NUMERIC(9, 0),
  "PERIODO"VARCHAR(3),
  "GRUPO"VARCHAR(5),
  "SUBGRUPO"VARCHAR(2),
  "FAMILIA"VARCHAR(5),
  "NUMERO"NUMERIC(9, 0),
  "DATA"DATE,
  "NOME"VARCHAR(40),
  "ESTADO"VARCHAR(2),
  "PROFISSAO"VARCHAR(14),
  "CPF"VARCHAR(11),
  "RESIDENCI"VARCHAR(40),
  "CIDADE"VARCHAR(30),
  "BAIRRO"VARCHAR(19),
  "CD_AREA_R"VARCHAR(5),
  "COBRANCA"VARCHAR(40),
  "BAIRRO_C"VARCHAR(30),
  "CIDADE_C"VARCHAR(30),
  "ESTADO_C"VARCHAR(2),
  "CEP"VARCHAR(10),
  "VALOR"NUMERIC(5, 2),
  "CODAREA"VARCHAR(5),
  "CODVEND"VARCHAR(5),
  "TIPO_VENDA"VARCHAR(5),
  "SITCOBRA"VARCHAR(1),
  "DATADELE"DATE,
  "MOTIVO"VARCHAR(12),
  "TAXAS"NUMERIC(9, 0),
  "CAREN_PG"DATE,
  "CAREN_AT"DATE,
  "TAXA_MAX"NUMERIC(9, 0),
  "ISENTO"VARCHAR(12),
  "ULT_REVIS"DATE,
  "DIAVENC"NUMERIC(9, 0),
  "OBSERVA"VARCHAR(60),
  "TELEFONE"VARCHAR(12),
  "INDICACAO"NUMERIC(9, 0),
  "COD_CANCE"VARCHAR(5),
  "SITUACAO"VARCHAR(2),
  "POS_DATA"DATE,
  "REGISTRO"VARCHAR(12),
  "EMPRESA"NUMERIC(9, 0),
  "CODRECUPER"VARCHAR(5),
  "DT_RECUPER"DATE,
  "VLR_PARTI"NUMERIC(9, 0),
  "DT_PROPOST"DATE,
  "CADUSUARIO"VARCHAR(10),
  "CADDATA"DATE,
  "CADHORA"VARCHAR(8),
  "DT_ULT_VLR"DATE,
  "DT_ULT_AUX"DATE,
  "SEGU_EMIS"DATE,
  "IDENTIDAD"VARCHAR(15)
);


Se quiser posso mandar o de dados pra vc mas creio que vai ter que ser por email....

Muito Obrigado...


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

23/01/2006

pode mandar por email:
emerson.en@gmail.com


GOSTEI 0
Geisonc

Geisonc

23/01/2006

Bom, depois de noites em claro, consegui !!
Caso alguem precise, ta aí o codigo !

SELECT a1.* from ARQ_HIST a1
WHERE (a1.PAGA is null) and (a1.venc between current_date -140 and current_date -5)
and not a1.inscricao in
(select a2.inscricao from arq_hist a2 where
(a2.inscricao = a1.inscricao) and (venc < current_date -140) and exists
(SELECT a2.inscricao from arq_nome where inscricao NOT IN
(SELECT inscricao FROM arq_nome WHERE fale IS NOT NULL))) order by inscricao


[]´s


GOSTEI 0
POSTAR