如何在postgresql中从sql结果中获得最大的结果

如何在postgresql中从sql结果中获得最大的结果,sql,postgresql,group-by,distinct-on,Sql,Postgresql,Group By,Distinct On,我正在使用postgresql 8.3,我有一个简单的sql查询: 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

我正在使用postgresql 8.3,我有一个简单的sql查询:

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
)
所以,我得到了这样一个结果集:

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
现在,我想通过实例_id获得max id,结果如下

id    instance_id  actor_id
150     53            24
161     57            26
167     58            23
我怎样才能得到结果?我使用下面的sql,但得到一个错误

错误:关系x不存在

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
          )
任何能帮助我的人,谢谢

试试这个:

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
结果说明:最后一行不同!:

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)
更新:这是一个查询,包括另一个子查询和缺少的表,以及原始难看的列名,都打包到一个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
        );
更新附录:

糟糕的是,8.3还没有CTE。考虑升级。好消息是:作为一种解决方法,您可以将zcte作为一个临时视图,并参考它。

@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
在大范围内,DISTINCT ON语法有时比已经给出的完全有效的答案要快

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

一旦习惯了这种语法,您可能会发现它比其他语法更容易阅读。在DISTINCT ON子句的括号内,您放置了应该是唯一的列列表,ORDER BY子句必须以匹配的列开始,并以足够的列继续,以确保您要保留的列位于第一位。

预期结果中的最后一行看起来是错误的:id=167大于id=165。打字错误?谢谢wildplasser,我已经修改了。+1个关于版本、确切错误消息等的好问题。谢谢。哦,非常非常好,我无法创建新表,但它对我仍然非常有用,谢谢同样的wildplasser。ThanksI省略了限制性subselect,但它可以作为额外的WHERE EXISTS子句添加。在大多数情况下,EXISTS比wrt NULL值更好。它还得到了较旧的实现的支持,而且不那么凌乱,是的,您的答案更简单,所以我选择了您的答案:不,这看起来是错误的。条件{12,23}仅在主查询中检查,而不在notexists分支中检查。尝试将第一个dt修改为CTE,如使用dt ASSELECT id,。。从实例WHERE EXISTS选择*FROM incident_info,其中task_instance=task_instance和{12,23},然后我的查询省略了表名,但带有dt引用
SELECT DISTINCT ON (instance_id)
  id, instance_id, actor_id
  FROM the_table dt
  ORDER BY instance_id, id DESC;