21

I have the following Postgres query:

SELECT array_agg("Esns".id ) 
FROM public."Esns", 
     public."PurchaseOrderItems" 
WHERE 
    "Esns"."PurchaseOrderItemId" = "PurchaseOrderItems".id 
    AND "PurchaseOrderItems"."GradeId"=2 
LIMIT 2;

The limit will affect the rows. I want it to limit the array_agg() to 2 items. The following query works but I get my output with each entry in quotes:

SELECT array_agg ("temp")  
FROM (
    SELECT "Esns".id 
    FROM public."Esns", 
         public."PurchaseOrderItems" 
    WHERE 
        "Esns"."PurchaseOrderItemId" = "PurchaseOrderItems".id 
        AND "PurchaseOrderItems"."GradeId"=2 
    LIMIT 4
) as "temp" ;

This give me the following output

{(13),(14),(15),(12)}

Any ideas?

2 Answers 2

30
select id[1], id[2]
from (
    SELECT array_agg("Esns".id ) as id
    FROM public."Esns", 
         public."PurchaseOrderItems" 
    WHERE 
        "Esns"."PurchaseOrderItemId" = "PurchaseOrderItems".id 
        AND "PurchaseOrderItems"."GradeId"=2 
) s

or if you want the output as array you can slice it:

SELECT (array_agg("Esns".id ))[1:2] as id_array
FROM public."Esns", 
     public."PurchaseOrderItems" 
WHERE 
    "Esns"."PurchaseOrderItemId" = "PurchaseOrderItems".id 
    AND "PurchaseOrderItems"."GradeId"=2 
Sign up to request clarification or add additional context in comments.

1 Comment

Perfect. Thanks. The second answer is what i was looking for as i do want an array and i want to be able to dynamically set the upper bound on the limit. Thank you.
6

The parentheses (not "quotes") in the result are decorators for the row literals. You are building an array of whole rows (which happen to contain only a single column). Instead, aggregate only the column.

Also, direct array construction from a query result is typically simpler and faster:

SELECT ARRAY (
   SELECT e.id 
   FROM   public."Esns" e
   JOIN   public."PurchaseOrderItems" p ON p.id = e."PurchaseOrderItemId"
   WHERE  p."GradeId" = 2 
   --  ORDER BY ???
   LIMIT  4  -- or 2?
   )

You need to ORDER BY something if you want a stable result and / or pick certain rows. Otherwise the result is arbitrary and can change with every next call.

While being at it I rewrote the query with explicit JOIN syntax, which is generally preferable, and used table aliases to simplify.

2 Comments

Are there cases where array constructor won't work and array_agg is needed? Constructor is able to replace all uses of array_agg that I have. Is there an equivalent constructor for json that could simplify or replace json_agg?
@user779159: Yes: Multiple array aggregations in the same SELECT list, Possibly with differing per-aggregate sort order.) JSON: no, but you can use ` to_jsonb(ARRAY(...))`.

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.