问题
I have a PostgreSQL database containing a table test_table with individual records. First column is a simple store_id, second column meausurement is a nested json.
store_id | measurement
----------------------
0 | {...}
The format of the measurement column is as follows:
{
'file_info': 'xxxx',
'data': {
'contour_data': {
'X': [-97.0, -97.0, -97.0, -97.0, -97.0, -97.0],
'Y': [-43.0, -41.0, -39.0, -39.0, -38.0, -36.0]
}
}
}
I would like to plot Y vs. X in a scatter plot in Tableau. Therefore I connected the database successfully with the PostgreSQL connector of Tableau. From this page I learned, that I have to use Custom SQL queries to extract data from the json object, since Tableau doesn't directly support the json datatype of Postgres. I tried already the following Custom SQL Query in Tableau:
select
store_id as store_id,
measurement#>>'{data, contour_data, X}' as contour_points_x,
measurement#>>'{data, contour_data, Y}' as contour_points_y
from test_table
which successfully extracts the two arrays to two new columns contour_points_x and contour_points_y. However both new columns are in Tableau of type string, so I cannot use them as data source for a plot.
How do I have to adjust the Custom SQL query to make the data arrays plottable in a Tableau scatter plot?
回答1:
Looks like you need to split the columns. Check this https://help.tableau.com/current/pro/desktop/en-us/split.htm
EDIT - the linked approach works when you can reliably assume an upper bound for the number of points in each list. One way to split arbitrarily sized lists is described here https://apogeeintegration.com/blog/apogee-busts-out-multi-value-cells-using-tableau-prep-builder
回答2:
The answer is a concatenation of several functions and/or syntax operations. One has to
- use the #> operator to dig in the
jsonand return it asjsontype (not astexttype as>>#does). - use json_array_elements_text() to expand the
jsonto a set oftext. - use type cast operator
::to converttexttofloat
/* custom SQL Query in Tableau */
select
store_id as store_id,
json_array_elements_text(measurement#>'{data, contour_data, X}')::float as contour_points_x,
json_array_elements_text(measurement#>'{data, contour_data, Y}')::float as contour_points_y,
from test_table
Both resulting columns appear in a Tableau Sheet now as discrete measures. Changing to discrete dimensions allows to plot contour_points_y vs. contour_points_x as desired.
来源:https://stackoverflow.com/questions/62423431/convert-postgresql-nested-json-to-numeric-array-in-tableau