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
  

Mensagemem Qui, 14 Jun 2007 9:46 am

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

Código: Selecionar todos
   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 :

Código: Selecionar todos
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
madmax
Localização: São Paulo

Mensagemem Sex, 15 Jun 2007 4:27 am

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:

Código: Selecionar todos
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:

Código: Selecionar todos
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;
rogenaro
Localização: Londrina - PR

Mensagemem Sáb, 16 Jun 2007 4:54 pm

Obrigado pela ajuda Rogenaro, irei testar na segunda feira no serviço e qualquer coisa do um toque aqui no forum valeu cara. !!! :D
madmax
Localização: São Paulo


  • Veja também
    Respostas
    ExibiÇões
    Última mensagem