1

This is my query in 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" 

And result is:

enter image description here

How to get only one row with minimum "ab" value?

I change this query to:

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" 

But get second row with ab = 347.783. What I am doing wrong?

4
  • Please tag correctly. Postgres isn't MySQL and isn't Oracle. Commented Mar 13, 2018 at 6:01
  • @ Sloan Thrasher, maybe there will be people, who khow the answer Commented Mar 13, 2018 at 6:03
  • They are too different in features and syntax. Commented Mar 13, 2018 at 6:07
  • @SloanThrasher DISTINCT ON has to be Postgres...but maybe the OP wanted a solution for any database. Commented Mar 13, 2018 at 6:13

2 Answers 2

4

You are missing an ORDER BY clause. You should be ordering first by the id, then by the ab column. Then, Postgres will return a single record for each id corresponding to the lowest ab value.

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;
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot, you save my day!
@Baurzhan Reload the page, I updated my answer. You need to ORDER BY id, ab, if you want to use DISTINCT ON (id).
0

You can use analytics function as well:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.