Skip to content
Advertisement

Calculating Datediff from nested json sql query

I am trying to use datediff() to find the age of a person in a postgres db (from their date of birth(. I know I can run datediff() like this

SELECT DATEDIFF(current_date, '2021-01-24');

The query i use to get date of birth is (its in json)

select date_of_birth from (select attrs::json->'info'->>'date_of_birth' from users) as date_of_birth;

This gives me output like

date_of_birth      
--------------
 (2000-11-03)
 (2000-06-11)
 (2000-05-31)
 (2008-11-26)
 (2007-11-09)
 (2020-03-26)
 (2018-06-30)

I tried using

SELECT DATEDIFF(current_date, (select date_of_birth from (select attrs::json->'info'->>'date_of_birth' as date_of_birth from users));

It doesn’t work. I tried several permutations but i can’t get it to work. How should I edit my query to calculate the user age?

Advertisement

Answer

This query:

select date_of_birth 
from (
  select attrs::json->'info'->>'date_of_birth' 
from users
) as date_of_birth;

Returns the row rather than a column, (the column expression for the extracted date value has no defined alias). It’s like using select users from users. You need to make `date_of_birth_ a column alias (not a table alias) and use that in the outer query.

To get the difference between two dates, just subtract them but you need to cast the valued to a date to be able to do that.

select current_date - u.date_of_birth 
from (
  select (attrs::json->'info'->>'date_of_birth')::date as date_of_birth
  from users
) as u;

Or without a derived table:

select current_date - (u.attrs::json->'info'->>'date_of_birth')::date
from users as u

Apparently your dates are stored in a non-standard format. In that case you can’t use as cast, but you need to use the to_date() function:

to_date(u.attrs::json->'info'->>'date_of_birth', 'mm:dd:yyyy')

If you are storing JSON in the attrs column you should convert it from a text (or varchar column to a proper json (or better jsonb) so you don’t need to cast it all the time.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement