Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Robson Rodrigues

SQL Quebrar e Agrupar por Semana

Recommended Posts

Ola. Tenho uma tabela com a seguinte estrutura:

 

DATA                PRODUTO QTE_VENDIDA

13/05/2018    12345        100

14/05/2018    12345        100

15/05/2018    12345        200

16/05/2018    12345        50

17/05/2018    12345        30

18/05/2018    12345        20

19/05/2018    12345        100

 

Gostaria de fazer um select que me agrupasse por semana dentro do periodo, algo como:

SEMANA INICIO SEMANA FIM  PRODUTO  QTDE VENDIDA

13/05/2018        19/05/2018     12345          600

20/05/2018        26/05/2018     12345          300

 

Alguém sabe me dizer como posso montar assim?

 

Obrigado

Compartilhar este post


Link para o post
Compartilhar em outros sites

Obrigado Motta pela dica.
Apenas não consegui montar a estrutura para chegar nesse modelo, tipo eu colocar um range de datas e dentro desse range ele montar essa quebra de semana com seus subtotais.
Você poderia me dar uma forma com um modelo a seguir?

Obrigado

Compartilhar este post


Link para o post
Compartilhar em outros sites

Um exemplo com a view USER_OBJECTS , a solução atende , até guardei nos meus alfarrábios pois pode vir a ser útil.

 

SELECT TO_CHAR(CREATED,'WW') "NUMERO DA SEMANA", 
       TO_CHAR(TRUNC(CREATED, 'IW')-1,'DD-MON-YYYY') "DIA INICIAL SEMANA", 
       TO_CHAR(NEXT_DAY(TRUNC(CREATED,'IW'),'SATURDAY'),'DD-MON-YYYY') "DIA FINAL DA SEMANA" ,
       COUNT(*) QTD
FROM   USER_OBJECTS
WHERE  CREATED >= TO_DATE('01/01/2018','DD/MM/YYYY')
GROUP BY TO_CHAR(CREATED,'WW') , 
       TO_CHAR(TRUNC(CREATED, 'IW')-1,'DD-MON-YYYY') , 
       TO_CHAR(NEXT_DAY(TRUNC(CREATED,'IW'),'SATURDAY'),'DD-MON-YYYY')
ORDER BY 1  

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Muito Obrigado Motta, era exatamente isso. resolveu meu problema.

 

Apenas fiz algumas alterações de tipo de campo para melhorar o ordenação e ficou assim:
 

SELECT TO_NUMBER(TO_CHAR(CREATED,'WW')) "NUMERO DA SEMANA", 
       TO_DATE(TO_CHAR(TRUNC(CREATED, 'IW')-1,'DD/MM/YYYY')) "DIA INICIAL SEMANA", 
       TO_DATE(TO_CHAR(NEXT_DAY(TRUNC(CREATED,'IW'),'SÁBADO'),'DD/MM/YYYY')) "DIA FINAL DA SEMANA" ,
       COUNT(*) QTD
FROM   USER_OBJECTS
WHERE  CREATED >= TO_DATE('01/01/2018','DD/MM/YYYY')
GROUP BY TO_CHAR(CREATED,'WW') , 
       TO_CHAR(TRUNC(CREATED, 'IW')-1,'DD/MM/YYYY') , 
       TO_CHAR(NEXT_DAY(TRUNC(CREATED,'IW'),'SÁBADO'),'DD/MM/YYYY')
ORDER BY 2 desc

 

Mais uma vez, muito obrigado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa Tarde Motta será que você poderia me dar uma força?
Montei o SQL conforme postei acima, até ai blz. O problema é que nele não esta aparecendo a semana do dia 15/07/2018 a 21/07/2018 que seria a semana 29 já pula para a semana 30.
Alguma ideia de porque isso possa estar ocorrendo?
Obrigado

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pior que tem. Existem movimento na tabela de vendas.
Outra coisa em tese essa base não é apenas para montar uma lista com as semanas independente de movimentação?
Tenho casos que que realmente não houve movimentação do produto nessa semana porem a semana aparece normal.
O que estou procurando entender por que pula essa semana.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Obrigado Motta, mas nesse caso não pois o que preciso são as datas de inicio e fim de cada semana.
 O exemplo que você montou para mim ficou bacana só não consegui entender porque somente nessa semana o fluxo quebra as outra carrega certinho.

Compartilhar este post


Link para o post
Compartilhar em outros sites

O exemplo citado do SO tem a vantagem de gerar datas sem precisar de uma tabela.

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

faça

CREATE OR REPLACE VIEW V_SEMANAS_ANO AS
SELECT
 to_char(CAL.DATA,'yyyy') ano,
 CAL.DATA,
 TO_NUMBER(TO_CHAR(CAL.DATA,'WW')) "NUMERO DA SEMANA",
 TO_DATE(TO_CHAR(TRUNC(CAL.DATA, 'IW')-1,'DD/MM/YYYY')) "DIA INICIAL SEMANA",
 TO_DATE(TO_CHAR(NEXT_DAY(TRUNC(CAL.DATA,'IW'),'saturday'),'DD/MM/YYYY')) "DIA FINAL DA SEMANA"--ou sabado        
FROM (
SELECT
  (
    TO_DATE(SEQ.MM || SEQ.YYYY, 'MM/YYYY')-1
    -- Subtrai 1 por SEQ.NUM não começar em zero
  ) + SEQ.NUM AS "DATA" 
    FROM
    (
        SELECT RESULT NUM, 
        TO_CHAR(( -- Data Mínima
            TO_DATE('01/01/2018', 'DD/MM/YYYY')
            ) , 'MM') AS "MM",
        TO_CHAR(( -- Data Mínima
            TO_DATE('01/01/2018', 'DD/MM/YYYY')
            ) , 'YYYY') AS "YYYY"
        FROM
          (
          SELECT ROWNUM RESULT FROM DUAL CONNECT BY LEVEL <= (
                (
                -- Data Máxima
                LAST_DAY(TO_DATE('31/12/2050', 'DD/MM/YYYY'))
                -
                -- Data Mínima
                TRUNC(TO_DATE('01/01/2018', 'DD/MM/YYYY')) -- Sempre primeiro dia do mês
                ) + 1 -- Último dia do último ano
            )
          ) -- Quantas sequências para gerar pelo MAX

    ) SEQ
) CAL
;
SELECT * FROM V_SEMANAS_ANO
where ano = '2018'
SELECT * FROM V_SEMANAS_ANO
where data = trunc(sysdate)

ANO  DATA     NUMERO DA SEMANA DIA INICIAL SEMANA DIA FINAL DA SEMANA
---- -------- ---------------- ------------------ -------------------
2018 31/08/18               35 26/08/18           01/09/18           

Acho que resolve até  31/12/2050

Compartilhar este post


Link para o post
Compartilhar em outros sites

  • Conteúdo Similar

    • Por ILR master
      Boa tarde, pessoal.
      Espero que todos estejam bem.
       
      Seguinte:
      Tenho a seguinte consulta:
       
      $usuarios= "SELECT * FROM usuarios";
      $query= mysqli_query($conexao, $usuarios) or die ("Usuário não encontrado");
      $usuario = mysqli_fetch_array($query);
       
      Quero pegar apenas o campo 'nome' da tabela 'usuarios' e colocar todos os resultados da seguinte forma:
       
      $nomes = array("Rafael", "João", "Maria", "Pedro", "Patricia", "Camila");
       
      Agradeço desde já.
      Abs
       
       
    • Por FabianoSouza
      Tenho uma function que precisa receber 02 argumentos.
      Ela funciona se eu aplicar num select qualquer. Mas se eu aplicar num select dinâmico, ocorre erro.
      Veja trecho do meu select.
      ... SET @sql = @sql +', dbo.retornaIco_ItemBloq((SELECT COUNT(*) FROM dbo.tab AS TT2 WHERE TT2.codCategTreina = CTT.id),'+@title+') AS ''resp''' ... No caso, o primeiro argumento da function dbo.retornaIco_ItemBloq é um SELECT COUNT.
      O segundo argumento é uma variável (que está devidamente declarada e definida).
       
      O erro ocorre porque ao executar (chamando EXEC(@sql) ), o SQL entende que o segundo argumento é uma coluna da consulta principal, pois existe uma vírgula antes da variável @title (que é o segundo argumento da function).
      Repito. Se eu aplicar essa function num select normal, funciona normalmente. Porém, preciso que funcione num SQL dinâmico porque é esse é o padrão que estou adotando para o sistema todo.
       
      A function dbo.retornaIco_ItemBloq faz o seguinte:
      1) Recebe o valor do COUNT e da variável @title
      2) Se o COUNT for maior que  Zero, cria uma tag HTML (uma SPAN), define sua title com o valor da variável @title e passa para uma variável
      3) Retorna o HTML que será exibido no resultado da consulta principal
      É super simples.
       
      Há outra forma de chamar a function?
    • Por mr22robot
      Ola caros amigos. 
      Estou com uma dúvida aqui que embora nao tenho achado ainda uma resposta, acredito que haja.
      Estou estudando a tão sonhada linguagem de programação asp.net core mvc. Linguagem essa que demorei 5 anos pra iniciar os estudos rsrs.
      Mas estou agarrado em uma situação. 
      Estou usando como base de dados nos meus estudos um banco Oracle. Que já tem algumas informações nele. Utilizei o SCAFFOLD para criar as classes e o contexto baseado no banco e tabelas existentes. 
      Porem agora na fase das consultas, estou perdido em como utilizar o IN que eu utilizo no oracle; no LINQ.
      Ex: 
      SELECT CODPROD,DESCRICAO FROM PRODUTO WHERE CODPROD IN(1,2,3,4,5,6) Como eu utilizo esse filtro com uma restrição de códigos de produtos? no caso o where codprod in(1,2,3,4,5,6) ?.
      Desde já obrigado pela ajuda.
    • Por Sapinn
      Olá a todos existe alguma maneira de trazer todos os dados de uma tabela menos o maior valor?
    • Por Wandersonwfs
      Bom dia Pessoal,
       
      Estou com um problema para finalizar uma consulta onde, quando executado a consulta  e não encontrado nenhuma informação no período solicitado, tenho que trazer pelo menos o nome da conta.
       
      Consulta,
       
      WITH TMPESTONO (
          NOME_IMPOSTO
          ,MES
          ,VALOR
          )
      AS (
          SELECT 'ESTORNO SOBRE GREEN VILLE' AS NOME_IMPOSTO
              ,'F_' + SZN.ZN_ITEM AS FILFOR
              ,SUM((SZN.ZN_PRV * SZN.ZN_PRCAPL) / 100) AS TOTAL
          FROM SZN010 SZN
          WHERE SZN.D_E_L_E_T_ = ' '
              AND SZN.ZN_ITEM IN (
                  '01'
                  ,'16'
                  ,'30'
                  ,'40'
                  ,'46'
                  ,'51'
                  ,'52'
                  ,'60'
                  ,'70'
                  ,'72'
                  ,'73'
                  ,'80'
                  )
              AND SZN.ZN_DATA BETWEEN '20220701'
                  AND '20220731'
              AND SZN.ZN_DESC = ('GRENVILLE')
          GROUP BY SZN.ZN_DESC
              ,SZN.ZN_ITEM
          )
      SELECT *
      FROM (
          SELECT NOME_IMPOSTO
              ,MES
              ,VALOR
          FROM TMPESTONO
          ) AS PivotData
      PIVOT(SUM(VALOR) FOR MES IN (
                  [F_16]
                  ,[F_30]
                  ,[F_40]
                  ,[F_46]
                  ,[F_51]
                  ,[F_52]
                  ,[F_60]
                  ,[F_70]
                  ,[F_72]
                  ,[F_73]
                  ,[TOTAL]
                  )) AS PivotTable2
      ORDER BY 1
       
×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.