0

Let us assume the following table: test

ids | l_ids      |  distance
-----------------+-----------
 53 | {150,40}   | {1.235, 2.265}
 22 | {20,520}   | {0.158, 0.568}

The positions of the two arrays (l_ids, distance) are dependent, meaning that 150 corresponds to 1.235, 40 corresponds to 2.265 and so on.

I want to get the min distance and the respective l_id. Therefore the result should be like this:

   ids | l_ids      |  distance
   ----------------+-----------
    53 |  150       |  1.235
    22 |   20       |  0.158

By running this:

select l_ids, min(dist) as min_distance 
from test, unnest(test.distance) dist
group by 1; 

the result is:

     l_ids      |  dist
    ------------+-----------
     {150,40}   |  1.235
     {20,520}   |  0.158

I want to get the position of the minimum value in the array of distance in order to get the respective id from the array of l_ids.

Any guideline? Thank you in advance

6
  • in distance array, values are unique? or may be {1.235, 1.235, 2.265} also happens? Commented Feb 15, 2017 at 15:22
  • The length of the arrays may be greater than 2, but always equal to each other. Commented Feb 15, 2017 at 15:24
  • can you have in l_ids for example: {150, 70, 40} and in distance these values: {1.235, 1.235, 2.265} (1.235 repeates) Commented Feb 15, 2017 at 15:26
  • Which PostgreSQL version do you use? Commented Feb 15, 2017 at 15:39
  • psql (9.5.4) version Commented Feb 15, 2017 at 15:40

3 Answers 3

2
SELECT DISTINCT ON (ctid) l_ids, distance
FROM (SELECT ctid,
             unnest(l_ids) AS l_ids,
             unnest(distance) AS distance
      FROM test
     ) q
ORDER BY ctid, distance;

 l_ids | distance
-------+----------
   150 |    1.235
    20 |    0.158
(2 rows)
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the reply. It works. Check please my edit in the question.
Use ids instead of ctid.
1

If ids are unique identiter, and you don't have repeated values in distance array, this should work:

SELECT a.* from  
(SELECT ids, UNNEST(l_ids) AS l_ids, UNNEST (distance) AS distance  FROM test) a
INNER JOIN (SELECT ids, MIN(distance) as mind FROM (
        SELECT ids,  UNNEST (distance) AS distance  FROM test 
    ) t
GROUP BY ids ) t
ON
a.ids = t.ids and a.distance = t.mind

3 Comments

Thanks, it s really closed to the solution. However it returns 12 rows more. I checked for duplicates. The ids are unique and there is no repeated value in distance.
As I said it s really closed. The query returns 10 duplicates of ids. However each duplicate has the same min distance, which is not critical for my further work. Thanks again for the assistance
So, its seems that you have duplicates in distance array, this causes more rows in result. glad if this was helpful for you.
1

From 9.4, you can use UNNEST()'s special ROWS FROM()-like syntax:

select   distinct on (ids) ids, l_id, dist min_distance
from     test, unnest(l_ids, test.distance) d(l_id, dist)
order by ids, dist

Otherwise, this is typical query.

1 Comment

+ for conciseness.

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.