cómo obtener el mayor resultado de un resultado sql en postgresql

Estoy usando postgresql 8.3 y tengo una consulta sql simple:

SELECT a.id,a.bpm_process_instance_id,a.actor_id 
  FROM bpm_task_instance a
 WHERE a.bpm_process_instance_id IN 
(
   SELECT bpm_process_instance_id 
         FROM incident_info 
        WHERE status = 12
          AND registrant = 23
)

Entonces, obtuve un conjunto de resultados como este:

id    instance_id  actor_id
150     53            24
147     53            26
148     53            25
161     57            26
160     57            26
158     57            24
165     58            23
166     58            24
167     58            24

ahora, quiero obtener la identificación máxima por instancia_id, y el resultado es como volar

id    instance_id  actor_id
150     53            24
161     57            26
167     58            23

como podria obtener el resultado Uso el siguiente sql, pero obtengo un error.

ERROR: relación "x" no existe

SELECT * 
  FROM (SELECT a.id,a.bpm_process_instance_id,a.actor_id 
          FROM bpm_task_instance a
         WHERE a.bpm_process_instance_id IN
            (
               SELECT bpm_process_instance_id 
                     FROM incident_info
                        WHERE status = 12
                      AND registrant = 23
            ) 
     ) AS x
 WHERE x.id = (
       SELECT max(id)
             FROM x 
            WHERE bpm_process_instance_id = x.bpm_process_instance_id
          )

quien me pueda ayudar, muchas gracias!

preguntado el 31 de julio de 12 a las 10:07

La fila final en el resultado deseado se ve mal: id=167 es mayor que id=165. ¿Error de tipografía? -

gracias wildplaser, lo he modificado. -

+1 buena pregunta con versiones, mensajes de error exactos, etc. Gracias. -

4 Respuestas

DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;

CREATE TABLE the_table
        ( id INTEGER NOT NULL
        , instance_id INTEGER NOT NULL
        , actor_id INTEGER NOT NULL
        );
INSERT INTO the_table(id, instance_id, actor_id) VALUES
(150,53,24) ,(147,53,26) ,(148,53,25)
,(161,57,26) ,(160,57,26) ,(158,57,24)
,(165,58,23) ,(166,58,24) ,(167,58,24)
        ;

SELECT id, instance_id, actor_id
FROM the_table dt
WHERE NOT EXISTS (
        SELECT *
        FROM the_table nx
        WHERE nx.instance_id = dt.instance_id
        AND nx.id > dt.id
        );

Resultado (nota: ¡la última fila es diferente!):

DROP SCHEMA
CREATE SCHEMA
SET
CREATE TABLE
INSERT 0 9
 id  | instance_id | actor_id 
-----+-------------+----------
 150 |          53 |       24
 161 |          57 |       26
 167 |          58 |       24
(3 rows)

ACTUALIZAR: esta es la consulta que incluye la otra subconsulta y la tabla que falta, y los nombres de columna originales (feos), todo empaquetado en un CTE:

WITH zcte AS (
        SELECT ti.id AS id
                , ti.bpm_process_instance_id AS instance_id
                , ti.actor_id AS actor_id
        FROM bpm_task_instance ti
        WHERE EXISTS ( SELECT * FROM incident_info ii
                WHERE ii.bpm_process_instance_id = ti.bpm_process_instance_id
                AND ii.status = 12
                AND ii.registrant = 23
                )
        )
SELECT id, instance_id, actor_id
FROM zcte dt
WHERE NOT EXISTS (
        SELECT *
        FROM zcte nx
        WHERE nx.instance_id = dt.instance_id
        AND nx.id > dt.id
        );

Apéndice de ACTUALIZACIÓN:

Vaya, la mala noticia es que 8.3 aún no tenía CTE. (piense en actualizar). La buena noticia es que, como solución alternativa, puede convertir zcte () en una VISTA (temporal) y consultarla en su lugar.

Respondido 01 ago 12, 13:08

oh, muy muy muy bien, no puedo crear una nueva tabla, pero me sigue siendo muy útil, gracias al mismo wildplasser. Gracias - diligente

Omití la subselección restrictiva, pero podría agregarse como una cláusula adicional "DONDE EXISTE ()". (en la mayoría de los casos, EXISTS () es mejor que IN () con valores NULL. También es compatible con implementaciones más antiguas y menos desordenado, en mi humilde opinión) - salvaje

sí, tu respuesta es más simple, así que elegí tu respuesta :) - diligente

prueba esto:

select a.id,a.bpm_process_instance_id,a.actor_id 
from bpm_task_instance A 
inner join
    (select max(a.id) as id,a.bpm_process_instance_id
    from bpm_task_instance a 
    where a.bpm_process_instance_id in 
        (  select bpm_process_instance_id 
           from incident_info 
           where status = 12 and registrant = 23
        )
group by a.bpm_process_instance_id)B
on A.bpm_process_instance_id=B.bpm_process_instance_id
and A.id=B.id

Respondido 31 Jul 12, 10:07

@wildplasser

    SELECT dt.* FROM 
    (
       SELECT id,bpm_process_instance_id,actor_id 
       FROM bpm_task_instance WHERE bpm_process_instance_id in 
       (
           SELECT bpm_process_instance_id FROM incident_info 
           WHERE status = 12 and registrant = 23
       ) 
    ) as dt
    WHERE NOT EXISTS (
        SELECT *
        FROM bpm_task_instance nx
        WHERE nx.bpm_process_instance_id = dt.bpm_process_instance_id
        AND nx.id > dt.id
    )
   ORDER BY id asc

Respondido 31 Jul 12, 11:07

No, eso se ve mal. La condición {12,23} solo se verifica en la consulta principal, no en el tramo NO EXISTE. Intente modificar el primer dt en un CTE, como WITH dt AS(SELECT id,.. FROM instance WHERE EXISTS (SELECT * FROM incident_info WHERE task_instance= task_instance AND {12,23} ) ) , seguido de mi consulta (omitiendo el nombre de la tabla, pero con la referencia dt) - salvaje

A gran escala, el DISTINCT ON la sintaxis es a veces más rápida que las respuestas perfectamente válidas ya dadas.

SELECT DISTINCT ON (instance_id)
  id, instance_id, actor_id
  FROM the_table dt
  ORDER BY instance_id, id DESC;

Una vez que se acostumbre a esta sintaxis, puede que le resulte más fácil de leer que las alternativas. Dentro de los paréntesis en el DISTINCT ON cláusula pones la lista de columnas que deben ser únicas, y el ORDER BY La cláusula debe comenzar con columnas coincidentes y continuar con suficientes columnas para asegurarse de que la que desea conservar sea la primera.

Respondido 31 Jul 12, 13:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.