【发布时间】:2022-01-02 14:02:09
【问题描述】:
以下是我的示例要求
我想要满足以下所有条件的客户
- 在“xyz”国家/地区,于 2019 年至 2021 年间注册。
- 应该至少有一个账户余额在 10000 到 13000 之间,分支是“abc”,交易日期在 20200110 到 20210625 之间。它被格式化并存储为数字
- 应至少有一个地址处于“state1”状态,并且 pin 码介于 625001 和 625015 之间
下面是表结构
CREATE TABLE customer_search_ms.customer
(
customer_id integer,
customer_details jsonb
)
表中可能有数百万行。 我在 customer_details 列上创建了 jsonb_ops 类型的 GIN 索引,因为我们还将检查存在条件和范围比较
以下是 customer_data JSONB 列中的示例数据
customer_id : 1
{
"customer_data": {
"name": "abc",
"incorporated_year": 2020,
"country":"xyz",
"account_details": [
{
"transaction_dates": [
20180125, 20190125, 20200125,20200525
],
"account_id": 1016084,
"account_balance": 2000,
"account_branch": "xyz"
},
{
"transaction_dates": [
20180125, 20190125, 20200125
],
"account_id": 1016087,
"account_balance": 12010,
"account_branch": "abc"
}
],
"address": [
{
"address_id": 24739,
"door_no": 4686467,
"street_name":"street1",
"city": "city1",
"state": "state1",
"pin_code": 625001
},
{
"address_id": 24730,
"door_no": 4686442,
"street_name":"street2",
"city": "city1",
"state": "state1",
"pin_code": 625014
}
]
}
}
现在我上面写的查询是
SELECT c.customer_id,
c.customer_details
FROM customer_search_ms.customer c
WHERE c.customer_details @@ CAST('$.customer_data.country == "xyz" && $.customer_data.incorporated_year >= 2019 && $.customer_data.incorporated_year <= 2021 ' AS JSONPATH)
AND c.customer_details @? CAST('$.customer_data.account_details[*] ? (@.account_balance >= 10000) ? (@.account_balance <= 13000) ?(@.account_branch == "abc") ? (@.transaction_dates >= 20200110) ? (@.transaction_dates <= 20210625)' AS JSONPATH)
AND c.customer_details @? CAST('$.customer_data.address[*] ? (@.state == "state1") ? (@.pin_code >= 625001) ? (@.pin_code <= 625015) ' AS JSONPATH)
处理上述情况是最好的写作方式。是否可以将所有 3 个条件(客户/帐户/地址)组合成一个表达式?该表将有数百万行。 我认为将其作为一种表达方式并点击数据库将提供最佳性能。是否可以将这三个条件组合为一个表达式
【问题讨论】:
-
使用适当的规范化数据模型会容易得多。
-
您的示例数据格式错误,第二个街道名称前缺少逗号。
-
你显示的查询没有给我你显示的错误。
标签: postgresql query-optimization database-performance jsonb