![](/img/trans.png)
[英]PostgreSQL update JSONB column from JSON string to Array of JSON objects
[英]Search by date in array of objects within PostgreSQL JSONB Column
我的 PostgreSQL 9.6 實例中有兩個表。
users
+----+------------+-----------+-------------------+
| id | first_name | last_name | email |
+----+------------+-----------+-------------------+
| 1 | John | Doe | john.doe@test.com |
+----+------------+-----------+-------------------+
| 2 | Jane | Doe | jane.doe@test.com |
+----+------------+-----------+-------------------+
| 3 | Mike | Doe | mike.doe@test.com |
+----+------------+-----------+-------------------+
surveys
+----+---------+----------------------------------------------------------------------------------------------------+
| id | user_id | survey_data |
+----+---------+----------------------------------------------------------------------------------------------------+
| 1 | 1 | {'child_list': [{'gender': 1, 'birthday': '2015-10-01'}, {'gender': 2, 'birthday': '2017-05-01'}]} |
+----+---------+----------------------------------------------------------------------------------------------------+
| 2 | 2 | {'child_list': []} |
+----+---------+----------------------------------------------------------------------------------------------------+
| 3 | 3 | {'child_list': [{'gender': 2, 'birthday': '2008-01-01'}]} |
+----+---------+----------------------------------------------------------------------------------------------------+
我希望能夠查詢這兩個表以獲取在特定年齡之間有孩子的用戶數量。 該survey_data
列surveys
表是JSONB列。
到目前為止,我已經嘗試將jsonb_populate_recordset
與LATERAL
連接一起使用。 我能夠將child_list
數組SELECT
為兩列,但無法弄清楚如何在users
和surveys
表之間使用我的JOIN
。 我使用的查詢如下:
SELECT DISTINCT u.email
FROM surveys
CROSS JOIN LATERAL (
SELECT *
FROM jsonb_populate_recordset(null::json_type, (survey.survey_data->>'child_list')::jsonb) AS d
) d
INNER JOIN users u ON u.id = survey.user_id
WHERE d.birthday BETWEEN '2014-05-05' AND '2018-05-05';
這也使用了使用此創建的自定義類型:
CREATE type json_type AS (gender int, birthday date)
我的問題是,有沒有更容易閱讀的方法來做到這一點? 我想將此查詢與許多其他JOIN
和WHERE
子句一起使用,我想知道是否有更好的方法來做到這一點。
注意:這主要由不需要超快但當然歡迎任何速度提升的報告系統使用。
使用函數jsonb_array_elements(),
示例:
select email, (elem->>'gender')::int as gender, (elem->>'birthday')::date as birthday
from users u
left join surveys s on s.user_id = u.id
cross join jsonb_array_elements(survey_data->'child_list') as arr(elem)
email | gender | birthday
-------------------+--------+------------
john.doe@test.com | 1 | 2015-10-01
john.doe@test.com | 2 | 2017-05-01
mike.doe@test.com | 2 | 2008-01-01
(3 rows)
或者
select distinct email
from users u
left join surveys s on s.user_id = u.id
cross join jsonb_array_elements(survey_data->'child_list') as arr(elem)
where (elem->>'birthday')::date between '2014-05-05' and '2018-05-05';
email
-------------------
john.doe@test.com
(1 row)
您可以使用視圖讓您的生活更輕松:
create view users_children as
select email, (elem->>'gender')::int as gender, (elem->>'birthday')::date as birthday
from users u
left join surveys s on s.user_id = u.id
cross join jsonb_array_elements(survey_data->'child_list') as arr(elem);
select distinct email
from users_children
where birthday between '2014-05-05' and '2018-05-05';
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.