Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PostgreSQL: row_to_json with selective columns [duplicate]

Task concept and my question

Using Postgres 9.4. How could I use row_to_json(row) with selective columns (not the entire row)? I need to discard one column from the row constructor while building JSON, but also need to preserve column names.

Restrictions

  1. Do not use self join to the same table/cte with selective columns choice
  2. Do not use external function to handle deleting key from json, afterwards

I'm well aware that I can write and use my own function to remove a key from JSON, or that in Postgres 9.5 there is - operator for JSONB. However, I would like to do this beforehand without additional function call and I'm pretty sure it's possible.

MVCE and explanation

Generating sample data

CREATE TABLE test_table ( id int, col1 int, col2 int, col3 text );
INSERT INTO test_table VALUES 
  (1, 23, 15, 'Jessica'), (2, 43, 84, 'Thomas');

1) First try, simple row_to_json(row), which is obviously not working:

SELECT id, row_to_json(t) FROM test_table t

I need to discard column id from the row constructor not to add it while parsing the row as json. Above returns:

 id |                  row_to_json
----+-----------------------------------------------
  1 | {"id":1,"col1":23,"col2":15,"col3":"Jessica"}
  2 | {"id":2,"col1":43,"col2":84,"col3":"Thomas"}

2) Second try, with explicit passing of columns row_to_json(row(col1, ...)):

SELECT id, row_to_json(row(col1, col2, col3)) FROM test_table t

But I'm losing column names (as mentioned in docs it all converts to fX, where X is a number:

 id |           row_to_json
----+----------------------------------
  1 | {"f1":23,"f2":15,"f3":"Jessica"}
  2 | {"f1":43,"f2":84,"f3":"Thomas"}

Expected output

Expected output is obviously from the (1) point in MVCE but without id key-value pair:

 id |                  row_to_json
----+-----------------------------------------------
  1 | {"col1":23,"col2":15,"col3":"Jessica"}
  2 | {"col1":43,"col2":84,"col3":"Thomas"}
like image 728
Kamil Gosciminski Avatar asked Oct 14 '16 11:10

Kamil Gosciminski


People also ask

How to query a JSON column in PostgreSQL?

PostgreSQL has two native operators -> and ->> to query JSON documents. The first operator -> returns a JSON object, while the operator ->> returns text. These operators work on both JSON as well as JSONB columns. There are additional operators available for JSONB columns.

What is Json_build_object in PostgreSQL?

The PostgreSQL json_build_object() function creates and returns a JSON object from a variadic parameter list consisting of alternating keys and values. This function is similar to the jsonb_build_object() function.

What is Json_agg in PostgreSQL?

Postgres offers us the json_agg() function, which takes an input values and aggregates them as a JSON array.

What is Json_build_object?

json_build_object(VARIADIC "any") Builds a JSON object out of a variadic argument list. By convention, the argument list consists of alternating keys and values.


1 Answers

It seems that creating a type with desired column names and matching data types and then casting the row to it will do the trick:

CREATE TYPE my_type AS (
  col1 int,
  col2 int,
  col3 text
);

Then altering my statement by adding the cast of row to defined type:

SELECT id, row_to_json(cast(row(col1, col2, col3) as my_type)) FROM test_table t;

Brings out the expected output:

 id |                  row_to_json
----+-----------------------------------------------
  1 | {"col1":23,"col2":15,"col3":"Jessica"}
  2 | {"col1":43,"col2":84,"col3":"Thomas"}

However, is there any method for this to be built without additional type?

like image 105
Kamil Gosciminski Avatar answered Sep 19 '22 06:09

Kamil Gosciminski