Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Postgres query result to json object

My query is given below

SELECT w.payload,
       Count('payload') OVER () AS ROWCOUNT
FROM wholesale_confirmation.wholesale_order_confirmation w
WHERE w.delivery_date = COALESCE(NULL, w.delivery_date)
  AND w.ship_to_location_id = COALESCE(NULL, w.ship_to_location_id)
  AND w.order_raised_date = COALESCE(NULL, w.order_raised_date)
  AND w.ship_from_location_id = COALESCE(NULL, w.ship_from_location_id)
LIMIT 10
OFFSET 0;

which is giving me result like this:

Result

I want instead {"payload:"[payload1,payload2,payload3],"rowcount":n}.


Postgres version 10.3, payload data type is jsonb

like image 298
pravinbhogil Avatar asked Apr 07 '18 23:04

pravinbhogil


People also ask

How do I return a JSON object in PostgreSQL?

The simplest way to return JSON is with row_to_json() function. It accepts a row value and returns a JSON value. select row_to_json(words) from words; This will return a single column per row in the words table.

Can you query JSON in Postgres?

Postgres is a relational database that allows you to combine relational and non-relational data effortlessly, giving users/applications flexibility in accessing and handling the data. Additionally, Postgres includes native support for querying and processing JSON data.

Which function converts a table row to JSON in PostgreSQL?

to_json() function Any SQL value can be converted to JSON using this PostgreSQL JSON function.

What is -> in Postgres?

Postgres offers 2 operators to get a JSON member: the arrow operator: -> returns type JSON or JSONB. the double arrow operator: ->> returns type text.


2 Answers

COALESCE(NULL, w.delivery_date) boils down to just w.delivery_date.

Consequently WHERE w.delivery_date = COALESCE(NULL, w.delivery_date) boils down to WHERE w.delivery_date IS NOT NULL.

Count('payload') OVER () AS ROWCOUNT is just a noisy way of saying count(*) OVER () AS rowcount and returns the total row count of the result.

Your current query, simplified:

SELECT payload, count(*) OVER () AS rowcount
FROM   wholesale_confirmation.wholesale_order_confirmation
WHERE  delivery_date          IS NOT NULL
AND    ship_to_location_id    IS NOT NULL
AND    order_raised_date      IS NOT NULL
AND    ship_from_location_id  IS NOT NULL
LIMIT  10;

To get a JSON object like in your updated question, containing one array of JSON objects and the total count of rows:

SELECT json_build_object('payload', jsonb_agg(payload), 'rowcount', min(rowcount))
FROM  (
   SELECT payload, count(*) OVER () AS rowcount
   FROM   wholesale_confirmation.wholesale_order_confirmation
   WHERE  delivery_date          IS NOT NULL
   AND    ship_to_location_id    IS NOT NULL
   AND    order_raised_date      IS NOT NULL
   AND    ship_from_location_id  IS NOT NULL
   LIMIT  10
   ) sub;
  • Best way to get result count before LIMIT was applied

If you are dealing with many rows, the performance with LIMIT / OFFSET degrades. Consider a more sophisticated pagination technique:

  • Optimize query with OFFSET on large table
like image 114
Erwin Brandstetter Avatar answered Oct 20 '22 23:10

Erwin Brandstetter


Use json_build_object:

WITH foobar AS ( 
SELECT w.payload,
       Count('payload') OVER () AS ROWCOUNT
FROM wholesale_confirmation.wholesale_order_confirmation w
WHERE w.delivery_date = COALESCE(NULL, w.delivery_date)
  AND w.ship_to_location_id = COALESCE(NULL, w.ship_to_location_id)
  AND w.order_raised_date = COALESCE(NULL, w.order_raised_date)
  AND w.ship_from_location_id = COALESCE(NULL, w.ship_from_location_id)
LIMIT 10
OFFSET 0
)

SELECT 
    json_build_object('payload', payload, 'rowcount', rowcount)
FROM 
    foobar 
like image 21
Michel Milezzi Avatar answered Oct 21 '22 01:10

Michel Milezzi