AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 46870
Accepted
riz
riz
Asked: 2013-07-24 07:26:46 +0800 CST2013-07-24 07:26:46 +0800 CST 2013-07-24 07:26:46 +0800 CST

Selecione qual tem data máxima ou data mais recente

  • 772

Aqui estão duas tabelas.

SCHOOL_STAFF

SCHOOL_CODE + STAFF_TYPE_NAME + LAST_UPDATE_DATE_TIME + PERSON_ID
=================================================================
ABE           Principal         24-JAN-13               111222
ABE           Principal         09-FEB-12               222111

PESSOAS

PERSON_ID + NAME
=================
111222      ABC
222111      XYZ

Aqui está minha consulta ao oráculo.

SELECT MAX(LAST_UPDATE_DATE_TIME) AS LAST_UPDATE, SCHOOL_CODE, PERSON_ID
FROM SCHOOL_STAFF
WHERE STAFF_TYPE_NAME='Principal'
GROUP BY SCHOOL_CODE, PERSON_ID
ORDER BY SCHOOL_CODE;

que dá este resultado

LAST_UPDATE SCHOOL_CODE PERSON_ID
===========+===========+=========
24-JAN-13   ABE         111222
09-FEB-12   ABE         222111

Eu quero selecionar o primeiro para a escola que tem data mais recente.

Obrigado.

oracle greatest-n-per-group
  • 3 3 respostas
  • 568166 Views

3 respostas

  • Voted
  1. Best Answer
    Taryn
    2013-07-24T07:31:28+08:002013-07-24T07:31:28+08:00

    Sua consulta atual não está dando o resultado desejado porque você está usando uma GROUP BYcláusula na PERSON_IDcoluna que tem um valor único para ambas as entradas. Como resultado, você retornará as duas linhas.

    Existem algumas maneiras de você resolver isso. Você pode usar uma subconsulta para aplicar a função de agregação para retornar o max(LAST_UPDATE_DATE_TIME)for each SCHOOL_CODE:

    select s1.LAST_UPDATE_DATE_TIME,
      s1.SCHOOL_CODE,
      s1.PERSON_ID
    from SCHOOL_STAFF s1
    inner join
    (
      select max(LAST_UPDATE_DATE_TIME) LAST_UPDATE_DATE_TIME,
        SCHOOL_CODE
      from SCHOOL_STAFF
      group by SCHOOL_CODE
    ) s2
      on s1.SCHOOL_CODE = s2.SCHOOL_CODE
      and s1.LAST_UPDATE_DATE_TIME = s2.LAST_UPDATE_DATE_TIME;
    

    Veja SQL Fiddle com demonstração

    Ou você pode usar uma função de janela para retornar as linhas de dados para cada escola com o mais recente LAST_UPDATE_DATE_TIME:

    select SCHOOL_CODE, PERSON_ID, LAST_UPDATE_DATE_TIME
    from
    (
      select SCHOOL_CODE, PERSON_ID, LAST_UPDATE_DATE_TIME,
        row_number() over(partition by SCHOOL_CODE 
                            order by LAST_UPDATE_DATE_TIME desc) seq
      from SCHOOL_STAFF
      where STAFF_TYPE_NAME='Principal'
    ) d
    where seq = 1;
    

    Veja SQL Fiddle com demonstração

    Essa consulta implementa row_number()que atribui um número exclusivo a cada linha na partição SCHOOL_CODEe colocada em ordem decrescente com base no arquivo LAST_UPDATE_DATE_TIME.

    Como nota lateral, a função JOIN com agregação não é exatamente igual à row_number()versão. Se você tiver duas linhas com o mesmo tempo de evento, o JOIN retornará as duas linhas, enquanto o row_number()retornará apenas uma. Se você deseja retornar ambos com uma função de janela, considere usar a rank()função de janela, pois ela retornará laços:

    select SCHOOL_CODE, PERSON_ID, LAST_UPDATE_DATE_TIME
    from
    (
      select SCHOOL_CODE, PERSON_ID, LAST_UPDATE_DATE_TIME,
        rank() over(partition by SCHOOL_CODE 
                            order by LAST_UPDATE_DATE_TIME desc) seq
      from SCHOOL_STAFF
      where STAFF_TYPE_NAME='Principal'
    ) d
    where seq = 1;
    

    Ver demonstração

    • 30
  2. Andrew
    2017-09-14T11:16:41+08:002017-09-14T11:16:41+08:00

    Estou surpreso que ninguém tenha aproveitado as funções da janela além do row_number ()

    Aqui estão alguns dados para brincar:

    CREATE TABLE SCHOOL_STAFF
    (
    LAST_UPDATE_DATE_TIME VARCHAR(20),
    SCHOOL_CODE VARCHAR(20),
    PERSON_ID VARCHAR(20),
    STAFF_TYPE_NAME VARCHAR(20)
    );
    INSERT INTO SCHOOL_STAFF VALUES ('24-JAN-13', 'ABE', '111222', 'Principal');
    INSERT INTO SCHOOL_STAFF VALUES ('09-FEB-12', 'ABE', '222111', 'Principal');
    

    A cláusula OVER() cria uma janela para a qual você definirá seus grupos agregados. Neste caso, estou particionando apenas no SHOOL_CODE, então veremos o FIRST_VALUE, que virá de LAST_UPDATE_DATE_TIME, agrupado por SCHOOL_CODE, e na ordem de LAST_UPDATE_DATE_TIME por ordem decrescente. Este valor será aplicado à coluna inteira para cada SCHOOL_CODE.

    É importante prestar muita atenção ao seu particionamento e ordenação na cláusula over().

    SELECT DISTINCT
     FIRST_VALUE(LAST_UPDATE_DATE_TIME) OVER (PARTITION BY SCHOOL_CODE ORDER BY LAST_UPDATE_DATE_TIME DESC) AS LAST_UPDATE
    ,FIRST_VALUE(SCHOOL_CODE)           OVER (PARTITION BY SCHOOL_CODE ORDER BY LAST_UPDATE_DATE_TIME DESC) AS SCHOOL_CODE
    ,FIRST_VALUE(PERSON_ID)             OVER (PARTITION BY SCHOOL_CODE ORDER BY LAST_UPDATE_DATE_TIME DESC) AS PERSON_ID
    FROM SCHOOL_STAFF
    WHERE STAFF_TYPE_NAME = 'Principal'
    ORDER BY SCHOOL_CODE
    

    Devoluções:

    24-JAN-13   ABE 111222
    

    Isso deve eliminar a maior parte da necessidade de GROUP BY e Subqueries. Você vai querer certificar-se de incluir DISTINCT.

    • 5
  3. MouseInfa
    2014-08-28T05:44:43+08:002014-08-28T05:44:43+08:00
    select LAST_UPDATE_DATE_TIME as LAST_UPDATE,
      SCHOOL_CODE,
      PERSON_ID
    from SCHOOL_STAFF
    WHERE STAFF_TYPE_NAME='Principal'
    AND LAST_UPDATE_DATE_TIME = (SELECT MAX(LAST_UPDATE_DATE_TIME)
                                FROM SCHOOL_STAFF s2
                                WHERE PERSON_ID = s2.PERSON_ID)
    
    • 2

relate perguntas

  • Backups de banco de dados no Oracle - Exportar o banco de dados ou usar outras ferramentas?

  • ORDER BY usando prioridades personalizadas para colunas de texto

  • Interface sqlplus confortável? [fechado]

  • Como encontrar as instruções SQL mais recentes no banco de dados?

  • Como posso consultar nomes usando expressões regulares?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Conceder acesso a todas as tabelas para um usuário

    • 5 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve