Ajuda em select (crosstab)

Dúvidas, dicas e truques de SQL, Select, Update, Delete, cláusulas, operações com joins, Funções em SQLs, etc
Avatar do usuário
madmax
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 293
Registrado em: Qua, 13 Dez 2006 5:02 pm
Localização: São Paulo
Contato:

Caros amigos estou com uma dificuldade neste select , este select pega tudo que e dia 01 e conta e subsequente ate o fim do mês por familia

Selecionar tudo

   Select 
    mp.Attribute1 Familia
     , count(decode(to_char(Spld.Creation_Date, 'DD'), '01' ,Spld.Lot_Number ) )  data01
     , count(decode(to_char(Spld.Creation_Date, 'DD'), '02' ,Spld.Lot_Number ) )  data02
     , count(decode(to_char(Spld.Creation_Date, 'DD'), '03' ,Spld.Lot_Number ) )  data03
     , count(decode(to_char(Spld.Creation_Date, 'DD'), '04' ,Spld.Lot_Number ) )  data04
     , count(decode(to_char(Spld.Creation_Date, 'DD'), '05' ,Spld.Lot_Number ) )  data05
     , count(decode(to_char(Spld.Creation_Date, 'DD'), '31' ,Spld.Lot_Number ) )  data31

    From
      Ra_Addresses_All               RA
     ,Ra_Site_Uses_All               RSU
     ,Ra_Customers                   RC
     ,So_Headers_All                 SH            
     ,So_Lines_All                   SLA
     ,Mtl_System_Items               MSI
     ,So_Line_Details                SLD
     ,So_Picking_Lines_All           SPLA
     ,So_Picking_Line_Details        SPLD
     ,apps.Mtl_Planners         mp    --- planejadores

   Where
      Spld.Creation_Date		   Between to_date('01-OCT-2006','DD-MON-YYYY') --:CG$CTRL.Dt_Ini 
      And to_date('30-OCT-2006','DD-MON-YYYY') --:CG$CTRL.Dt_Ini And :CG$CTRL.Dt_Fim + .99999
      And Spld.Warehouse_Id      	   = 45 --:parameter.Organization_Id   
      And Spla.Picking_Line_Id   	   = Spld.Picking_Line_Id   
      And Spla.Warehouse_Id      	   = Spld.Warehouse_Id    
      And Sld.Line_Id            	   = Spla.Order_Line_Id
      And Sld.Lot_Number         	   = Spld.Lot_Number 
      And Sld.Warehouse_Id       	   = Spld.Warehouse_Id
      And Msi.Inventory_Item_Id  	   = Sld.Inventory_Item_Id
      And Msi.Organization_Id    	   = Sld.Warehouse_Id
      And Sla.Line_Id            	   = Spla.Order_Line_Id
      And Sla.Warehouse_Id       	   = Spla.Warehouse_Id
      And Sh.Header_Id           	   = Sla.Header_Id
      And Sh.Warehouse_Id        	   = Sla.Warehouse_Id 
      And Rc.Customer_Id         	   = Sh.Customer_Id
      And Rsu.Site_Use_Id        	   = Sh.Ship_To_Site_Use_Id
      And Ra.Address_Id          	   = Rsu.Address_Id
      and mp.Planner_Code       = msi.Planner_Code
      and mp.Attribute1  is not null

     Group by 
   mp.Attribute1

O Resultado e Esse :

Selecionar tudo

FAMILIA   DATA01   DATA02   DATA03   DATA04   DATA05   DATA31
CAN       15       104      175      81       87       0
EXPIPG    0        0        0        28       102      0
FSTOCK    11       24       23       33       47       0
INDUST    0        35       74       1        53       0
IPG       21       215      162      135      112      0

O Problema e que tenho que fazer o seguinte o dia diferente agora vai das 07:00 do dia 01 ate 07:00 do dia 02 somando para a DATA01 ou dia 01 e subseguente ate o ultimo dia do mês que ficara ate 00:00 como fazer isso via select alguém tem uma ideia .. estou aceitando qualquer coisa rsrsrs... um abraço :-o
rogenaro
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Sex, 30 Mar 2007 7:26 pm
Localização: Londrina - PR

Não é das melhores soluções, mas até onde testei parece funcionar (eu usei uma tabela mais simples, mas acho que dá para entender o que foi feito comparando as duas versões):

Considerando o dia da 00:00:00 às 23:59:59 do mesmo dia:

Selecionar tudo

select codigo
, count(decode(to_char(data, 'DD'), '01' ,tipo ) ) data01
, count(decode(to_char(data, 'DD'), '02' ,tipo ) ) data02
, count(decode(to_char(data, 'DD'), '03' ,tipo ) ) data03
, count(decode(to_char(data, 'DD'), '04' ,tipo ) ) data04
from t03 a
where a.data between to_date(20070101, 'yyyymmdd') and to_date(20070131, 'yyyymmdd')
group  by a.codigo
order by 1;

Considerando o dia das 07:00:00 às 06:59:59 do próximo dia:

Selecionar tudo

select codigo
, count(decode(to_char(dat_ini, 'DD'), '01' ,tipo ) ) data01
, count(decode(to_char(dat_ini, 'DD'), '02' ,tipo ) ) data02
, count(decode(to_char(dat_ini, 'DD'), '03' ,tipo ) ) data03
, count(decode(to_char(dat_ini, 'DD'), '04' ,tipo ) ) data04
from t03 a
,
(
select to_date(20070101, 'yyyymmdd') + 
         rownum - ((24-7)/24)                  dat_ini
       -- Todos os dias do mês, a partir das 07:00:00 
       -- (utilizar a data inicial como parâmetro)

     , to_date(20070101, 'yyyymmdd') + 
       rownum - ((24-7)/24)-(1/(24*60*60))+1 dat_fim
       -- 06:59:59 do próximo dia (utilizar a data inicial como parâmetro)

--  Usar a all_objects, ou qualquer outra tabela 
--  de seu sistema que certamente trará um número 
--  suficiente de linhas (cada dia de período de leitura 
--  irá retornar uma linha) 
--  Se você estiver na versão 10g (ou talvez na 9i 
--  também funcione), é mais garantido utilizar 
--  select ... from dual connect by level <= ...
from all_objects
--  Busca quantos dias deverão ser trazidos 
--  (parâmetro data final + 1 -  data inical)
where rownum <= to_date(20070131, 'yyyymmdd')+1 - to_date(20070101, 'yyyymmdd')
) b
where a.data between b.dat_ini and b.dat_fim
group  by a.codigo
order by 1;
Avatar do usuário
madmax
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 293
Registrado em: Qua, 13 Dez 2006 5:02 pm
Localização: São Paulo
Contato:

Obrigado pela ajuda Rogenaro, irei testar na segunda feira no serviço e qualquer coisa do um toque aqui no forum valeu cara. !!! :D
Responder
  • Informação
  • Quem está online

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