em Uncategorized

SQL – como agrupar registros por uma coluna e pegar o último pela data

Não sou bom com SQL – nunca fui, nunca quis me aprofundar e tenho um certo bloqueio com relação a isso.
Mas, algumas vezes tenho que mexer com isso, e sempre me deparo com alguns erros bobos ou algumas coisas mais complexas.

No caso, incrivelmente as questões bobas não me atrapalharam, mas quebrei a cabeça quando tinha uma tabela com uma estrutura mais ou menos semelhante a essa (vou suprimir as colunas que não interessam para o problema):

  • id: id primário, auto-incremente
  • f_id: é uma relação de cada registro com registros de outra tabela. Não é único
  • adddate: data do registro
  • nome: nome do registro

Minha necessidade era agrupar os registros por esse f_id e retornar a data mais recente de cada grupo.
À princípio estava tentando fazer um SELECT e agrupar por GROUP BY, dando um ORDER BY depois, mas percebi que uma vez usado o GROUP BY nada garante qual é o registro que ele vai usar quando der um ORDER BY.
Vi então que a coisa seria mais séria, e que teria que usar SUBSELECTS… estava quebrando a cabeça e o Alexandre (@kurko) me ajudou após um pedido de SOS pelo twitter, e a seguinte query abaixo me salvou!

SELECT u.f_id, u.nome, ( SELECT adddate FROM usuario AS t WHERE t.f_id=u.f_id ORDER BY t.adddate DESC LIMIT 1) as data FROM usuario AS u GROUP BY u.f_id ORDER BY u.f_id

Espero que seja de utilidade!

Deixa uma resposta para JÚLIO FIRMO NETO Cancelar resposta

Escreva um comentário

Comentário

  1. SELECT
    PRODUTO,
    DESCR,
    UM,
    SUM(ISNULL(PRECO,0)) PRECO,
    SUM(ISNULL(CUSTO,0)) CUSTO,
    SUM(ISNULL(ESTOQUE,0)) ESTOQUE,
    SUM(ISNULL(C_NOVAS_COMPRAS,0)) C_NOVAS_COMPRAS,
    VALIDADE_NOVAS_COMPRAS,
    SUM(C_MERCADO) C_MERCADO,
    VALIDADE_MERCADO

    FROM
    (
    SELECT
    DA1_CODPRO PRODUTO,
    B1_DESC DESCR,
    B1_UM UM,
    DA1_PRCVEN PRECO,
    0 CUSTO,
    0 ESTOQUE,
    0 C_NOVAS_COMPRAS,
    ” VALIDADE_NOVAS_COMPRAS,
    0 C_MERCADO,
    ” VALIDADE_MERCADO

    FROM
    DA1010 DA1 WITH(NOLOCK)
    INNER JOIN SB1010 SB1 WITH(NOLOCK) ON
    B1_FILIAL = ”
    AND B1_COD = DA1_CODPRO
    AND SB1.D_E_L_E_T_ ‘*’

    WHERE
    DA1.D_E_L_E_T_ ‘*’
    AND DA1_CODTAB = ‘F01’

    UNION ALL
    SELECT
    CODIGO,
    DESCRICAO,
    UM,
    0 PRECO,
    CUSTO,
    ESTOQUE,
    0 C_NOVAS_COMPRAS,
    ” VALIDADE_NOVAS_COMPRAS,
    0 C_MERCADO,
    ” VALIDADE_MERCADO

    FROM
    DwFuturagro.DBO.TB_ESTXCUSTO
    INNER JOIN DA1010 DA1 WITH(NOLOCK) ON
    FILIAL = ‘031’
    AND CODIGO = DA1_CODPRO
    AND DA1_CODTAB = ‘F01’
    AND DA1.D_E_L_E_T_ ‘*’

    UNION ALL

    SELECT
    ZBQ_COD PRODUTO,
    ZBQ_DESC DESCR,
    B1_UM UM,
    0 PRECO,
    0 CUSTO,
    0 ESTOQUE,
    ZBQ_CUSTO C_NOVAS_COMPRAS,
    ZBQ_VALCUS VALIDADE_NOVAS_COMPRAS,
    ZBQ_CUSMER C_MERCADO,
    ZBQ_VALCME VALIDADE_MERCADO
    FROM
    ZBQ010 ZBQ WITH(NOLOCK)
    LEFT JOIN SB1010 SB1 WITH(NOLOCK) ON
    B1_FILIAL = ”
    AND B1_COD = ZBQ_COD
    AND SB1.D_E_L_E_T_ ‘*’
    WHERE
    ZBQ.D_E_L_E_T_ ‘*’
    ) TRB
    WHERE PRODUTO = ‘100000209380126’
    GROUP BY
    PRODUTO,
    DESCR,
    UM,
    VALIDADE_NOVAS_COMPRAS,
    VALIDADE_MERCADO

    Resultado
    –Como faço para unificar essas duas linhas?
    PRODUTO DESCR UM PRECO CUSTO ESTOQUE C_NOVAS_COMPRAS VALIDADE_NOVAS_COMPRAS C_MERCADO VALIDADE_MERCADO
    100000209380126 FLAK 200 SL BD 20 LTS – OR-2 L 19,44 16,17 60 0 0
    100000209380126 FLAK 200 SL BD 20 LTS – OR-2 L 0 0 0 0 20191207 11,1 20191207