Me di cuenta de que una consulta de base de datos fue devolver resultados inesperados hacer para mi uso indebido de los «DISTINTOS» y «GRUPO»

Estoy esperando que alguien puede me puso directamente en este. La consulta real es bastante complejo , así que voy a tontas :

Tengo una tabla/consulta interna que consta de un object_id y una marca de tiempo:

CREATE TABLE test_select ( object_id INT , event_timestamp timestamp );
COPY test_select (object_id , event_timestamp) FROM stdin (DELIMITER '|');
1           | 2013-01-27 21:01:20
1           | 2012-06-28 14:36:26
1           | 2013-02-21 04:16:48
2           | 2012-06-27 19:53:05
2           | 2013-02-03 17:35:58
3           | 2012-06-14 20:17:00
3           | 2013-02-15 19:03:34
4           | 2012-06-13 13:59:47
4           | 2013-02-23 06:31:16
5           | 2012-07-03 01:45:56
5           | 2012-06-11 21:33:26
\.

Estoy tratando de seleccionar una clara IDENTIFICACIÓN , ordenado/desduplicados por la marca de tiempo en el reverso de chron

por lo que los resultados deben ser [ 4, 1, 3, 2, 5 ]

Creo que esto no hace lo que yo necesito (parece ):

SELECT object_id  
FROM test_select 
GROUP BY object_id 
ORDER BY max(event_timestamp) DESC
;

Para pruebas/fines de auditoría , a veces me quiere incluir un campo de marca de hora. Me parece que no puede averiguar cómo incluir otro campo con esa consulta.

Puede alguien señalar problemas evidentes en mi sql anterior, o sugerencias sobre cómo incluir la auditoría de información ?

OriginalEl autor Jonathan Vanasco | 2013-09-22

2 Comentarios

  1. 17

    Para ser capaz de seleccionar todas las columnas y no sólo object_id y MAX(event_timestamp), puede utilizar DISTINCT ON

    SELECT DISTINCT ON (object_id) 
        object_id, event_timestamp    ---, more columns
    FROM test_select 
    ORDER BY object_id, event_timestamp DESC ;

    Si desea que los resultados se ordenan por event_timestamp DESC y no por object_id, que debe incluir en una tabla derivada o una CTE:

    SELECT *
    FROM 
      ( SELECT DISTINCT ON (object_id) 
            object_id, event_timestamp    ---, more columns
        FROM test_select 
        ORDER BY object_id, event_timestamp DESC 
      ) AS t
    ORDER BY event_timestamp DESC ;

    Alternativamente, puede utilizar las funciones de la ventana, como ROW_NUMBER():

    WITH cte AS
      ( SELECT ROW_NUMBER() OVER (PARTITION BY object_id 
                                  ORDER BY event_timestamp DESC) 
                 AS rn, 
               object_id, event_timestamp    ---, more columns
        FROM test_select 
      )
    SELECT object_id, event_timestamp    ---, more columns
    FROM cte
    WHERE rn = 1
    ORDER BY event_timestamp DESC ;

    o agregado MAX() con OVER:

    WITH cte AS
      ( SELECT MAX(event_timestamp) OVER (PARTITION BY object_id) 
                 AS max_event_timestamp, 
               object_id, event_timestamp    ---, more columns
        FROM test_select 
      )
    SELECT object_id, event_timestamp    ---, more columns
    FROM cte
    WHERE event_timestamp = max_event_timestamp
    ORDER BY event_timestamp DESC ;
    Gracias! El segundo ejemplo de sintaxis yo estaba tratando de entender. Voy a probar las otras consultas para el rendimiento más tarde y ver si los puedo usar. Estoy construyendo esta consulta generativamente según la entrada del usuario, y que el segundo ejemplo es «fácilmente realizable».

    OriginalEl autor ypercubeᵀᴹ

  2. 3

    Probablemente no es la mejor manera de lidiar con esto, pero usted puede intentar el uso de la función de la ventana:

    SELECT DISTINCT object_id, MAX(event_timestamp)
    OVER (PARTITION BY object_id)  
    FROM test_select ORDER BY max DESC;

    Desde el otro lado funciona así:

    SELECT object_id, MAX(event_timestamp) as max_event_timestamp
    FROM test_select 
    GROUP BY object_id 
    ORDER BY max_event_timestamp DESC;

    OriginalEl autor zero323

Dejar respuesta

Please enter your comment!
Please enter your name here