AJUDA EM SQL

Dúvidas, dicas e truques de SQL, Select, Update, Delete, cláusulas, operações com joins, Funções em SQLs, etc
manusud
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 7
Registrado em: Sex, 28 Mai 2010 11:33 am
Localização: Campinas - SP
Contato:
Nenhum sucesso na vida compensa o fracasso no lar

Boa tarde !!

Eu tentei de várias formas aqui e não consegui.

Por gentileza, eu preciso fazer um SELECT que me traga qual filial da empresa fez uma venda, fora do horário autorizado.

Eu tenho duas tabelas:

Tabela de Vendas
Tabela de horários autorizados

A tabela de vendas contém os seguintes campos:

Nome campo Tipo
data_hora_venda date (dd/mm/yyyy hi:mi:ss)
numero_filial number
valor_venda number

A tabela de horários autorizados contém os seguintes campos:

Nome campo Tipo
dt_hr_inicio date (dd/mm/yyyy hi:mi:ss)
dt_hr_fim date (dd/mm/yyyy hi:mi:ss)
numero_filial number

OBS: Na tabela de vendas há vendas de vários dias em vários horários de várias filiais.
Na tabela de horários autorizados, temos vários intervalos de horários no mesmo dia para cada filial.
DanielNN
Moderador
Moderador
Mensagens: 641
Registrado em: Seg, 03 Set 2007 3:26 pm
Localização: Fortaleza - CE
att,

Daniel N.N.

Se você quer apenas as vendas fora dos horários cadastrados nesta tabela de horários, e supondo todos gravarem informações de hora minuto e segundo, então acredito que o seguinte resolva:

Selecionar tudo

SELECT *
  FROM VENDAS V
  JOIN HORARIOS H ON ( V.NUMERO_FILIAL = H.NUMERO FILIAL)
 WHERE V.DATA_HORA_VENDA NOT BETWEEN DT_HR_INICIO AND DT_HR_FIM
Avatar do usuário
stcoutinho
Moderador
Moderador
Mensagens: 850
Registrado em: Qua, 11 Mai 2011 5:15 pm
Localização: são Paulo - SP

Olá manusud,

Acho que existem diferentes soluções para seu problema. Vou postar aqui uma solução que TALVEZ resolva seu problema, mas tenho certeza que os foristas dispõe de outras sugestões, talvez mais fáceis que a minha:

Primeiro, vamos montar uma querie que indica se uma venda não se encaixa nos horarios liberados para a filial:

Selecionar tudo

-- Esta querie bate as vendas com os horarios permitidos
-- Se um deles estiver dentro das horas autorizadas, marca autorizado como "S"
SELECT V.NUMERO_FILIAL,
       V.DATA_HORA_VENDA,
       H.DT_HR_INICIO,
       H.DT_HR_FIM,
       CASE WHEN V.DATA_HORA_VENDA NOT BETWEEN H.DT_HR_INICIO AND H.DT_HR_FIM 
                         THEN 'N' 
                          ELSE 'S' END AS AUTORIZADO
  FROM VENDA V,
       HORARIO_AUTORIZADO H
 WHERE V.NUMERO_FILIAL = H.NUMERO_FILIAL


A querie acima faz um produto cartesiano entre VENDAS e os HORARIOS AUTORIZADOS de uma mesma filial. Ela parece uma "querie burra", pois um "dia/hora venda" será comparado com vários "dias/horas autorizados". Pode ser que esta venda se encaixe em um dos horarios autorizados ou em nenhum deles. Mas vamos deixar ela como está, pois depois a usaremos em outra querie maior. Se a venda se encaixa em algum horario permitido, então marcará uma coluna AUTORIZADO com "SIM". Caso contrário, com "não"

Agora, vamos passar um filtro nesta queire, para que ele nos retorne somente as vendas autorizadas, ou seja, somente as vendas de uma filial que estejam em um dos intervalos permitidos. Se alguma venda foi feita em horario não permitido, ela não aparecera aqui.

Selecionar tudo

-- Esta querie filtra todos os horarios de venda permitidos
-- Uma venda de filial que não se encaixe em um periodo permitido não será mostrada aqui

SELECT Z.NUMERO_FILIAL,
       Z.DATA_HORA_VENDA
 FROM  (-- Esta querie bate as vendas com os horarios permitidos       
        -- Se um deles estiver dentro das horas autorizadas, marca autorizado como "S"
        SELECT V.NUMERO_FILIAL,
               V.DATA_HORA_VENDA,
               H.DT_HR_INICIO,
               H.DT_HR_FIM,
               CASE WHEN V.DATA_HORA_VENDA NOT BETWEEN H.DT_HR_INICIO AND H.DT_HR_FIM 
                       THEN 'N' ELSE 'S' END AS AUTORIZADO
          FROM VENDA V,
               HORARIO_AUTORIZADO H
         WHERE V.NUMERO_FILIAL = H.NUMERO_FILIAL
        ) Z
 WHERE Z.AUTORIZADO = 'S'        
E agora, vamos montar a querie mais simples de todas, que mostra TODAS as vendas ocorridas

Selecionar tudo

-- Esta querie relaciona todas as vendas, autorizadas ou não
SELECT V.NUMERO_FILIAL,
       V.DATA_HORA_VENDA 
  FROM VENDA
Pronto .. temos todas as informações que precisamos: "todas as vendas das filiais" e "vendas autorizadas das filiais".

Se subtrairmos as "vendas autorizadas" das "vendas totais", chegaremos nas "vendas irregulares". Para isso uso a função MINUS e construo a querie final:

Selecionar tudo

-- Esta querie mostra somente as vendas irregulares
SELECT W.NUMERO_FILIAL
       W.DATA_HORA_VENDA
FROM       
(
-- Esta querie relaciona todas as vendas, autorizadas ou não
SELECT V.NUMERO_FILIAL,
       V.DATA_HORA_VENDA 
  FROM VENDA
MINUS
-- Esta querie filtra todos os horarios de venda permitidos
-- Uma venda de filial que não se encaixe em um periodo permitido não será mostrada aqui
SELECT Z.NUMERO_FILIAL,
       Z.DATA_HORA_VENDA
 FROM  (-- Esta querie bate as vendas com os horarios permitidos       
        -- Se um deles estiver dentro das horas autorizadas, marca autorizado como "S"
        SELECT V.NUMERO_FILIAL,
               V.DATA_HORA_VENDA,
               H.DT_HR_INICIO,
               H.DT_HR_FIM,
               CASE WHEN V.DATA_HORA_VENDA NOT BETWEEN H.DT_HR_INICIO AND H.DT_HR_FIM 
                  THEN 'N' ELSE 'S' END AS AUTORIZADO
          FROM VENDA V,
               HORARIO_AUTORIZADO H
         WHERE V.NUMERO_FILIAL = H.NUMERO_FILIAL
        ) Z
 WHERE Z.AUTORIZADO = 'S'        
) W         

Não tenho como garantir que a querie acima está 100% certa. Você precisaria testar em sua massa de dados.

Talvez os foristas tenham outras sugestões bem mais simples do que a minha.

Abraços,

Sergio Coutinho
Editado pela última vez por stcoutinho em Qui, 23 Jan 2014 10:27 am, em um total de 1 vez.
Razão: O comentario foi revisado posteriormente com relacao as variaveis da querie (SIM->"S" e NAO->"N")
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 17 visitantes