gpt4 book ai didi

sql - 按日期搜索 PostgreSQL JSONB 列中的对象数组

转载 作者:行者123 更新时间:2023-11-29 13:12:49 25 4
gpt4 key购买 nike

我的 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'}]} |
+----+---------+----------------------------------------------------------------------------------------------------+

我希望能够查询这两个表以获取在特定年龄段拥有 child 的用户数量。 surveys 表中的 survey_data 列是一个 JSONB 列。

到目前为止,我已尝试将 jsonb_populate_recordsetLATERAL 连接一起使用。我能够将 SELECT child_list 数组作为两列,但无法弄清楚如何在 users 之间的 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)

我的问题是,有没有更容易阅读的方法来做到这一点?我想将此查询与许多其他 JOINWHERE 子句一起使用,我想知道是否有更好的方法。

注意:这主要用于不需要超快的报告系统,当然欢迎任何速度提升。

最佳答案

使用函数 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)

您可以使用 View 让您的生活更轻松:

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';

关于sql - 按日期搜索 PostgreSQL JSONB 列中的对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52742174/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com