postgresql选择具有最小值的行

时间:2018-03-13 05:59:36

标签: postgresql postgresql-9.1 postgresql-9.3

这是我在PostgreSQL中的查询:

SELECT 
    "axapta_calls".id, 
    "axapta_calls".call_time, 
    calls.calltime, 
    "calls"."id" as "call_id",  
    abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp))) as ab 
FROM 
    "axapta_calls" 
inner join 
    "calls" (ON 
        axapta_calls.converted_outer_phone=calls.caller_phone
        and abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp)))<= 600 )
WHERE  ("axapta_calls"."id" > 0) 
GROUP BY "axapta_calls"."id", "calls"."id" 

结果是:

enter image description here

如何只获得一个最小“ab”值的行?

我将此查询更改为:

SELECT 
    distinct on (axapta_calls.id)
    "axapta_calls".id, 
    "axapta_calls".call_time, 
    calls.calltime, 
    "calls"."id" as "call_id",  
    abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp))) as ab 
FROM 
    "axapta_calls" 
inner join 
    "calls" ON 
        axapta_calls.converted_outer_phone=calls.caller_phone
        and abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp)))<= 600 
WHERE  ("axapta_calls"."id" > 0) 
GROUP BY "axapta_calls"."id", "calls"."id" 

但是得到第二行,ab = 347.783。我做错了什么?

2 个答案:

答案 0 :(得分:2)

您缺少ORDER BY条款。您应首先按id订购,然后按ab列订购。然后,Postgres将为每个id返回与最低ab值对应的单个记录。

SELECT 
    distinct on (axapta_calls.id),
    "axapta_calls".id, 
    "axapta_calls".call_time, 
    calls.calltime, 
    "calls"."id" as "call_id",  
    abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp))) as ab 
FROM 
    "axapta_calls" 
inner join "calls"
    ON axapta_calls.converted_outer_phone=calls.caller_phone and
       abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp)))<= 600 )
WHERE  ("axapta_calls"."id" > 0)
ORDER BY
    axapta_calls.id, 5;

答案 1 :(得分:0)

您也可以使用分析功能:

select *
from 
(SELECT 
    "axapta_calls".id, 
    "axapta_calls".call_time, 
    calls.calltime, 
    "calls"."id" as "call_id",  
    abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp))) as ab,
    rank() OVER (ORDER BY ab )rnk
FROM 
    "axapta_calls" 
inner join 
    "calls" (ON 
        axapta_calls.converted_outer_phone=calls.caller_phone
        and abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp)))<= 600 )
WHERE  ("axapta_calls"."id" > 0) )
where rnk=1