sql - PostgreSQL 与 json 数组中的模式反向 LIKE

标签 sql json postgresql

此问题与 PostgreSQL Reverse LIKE 相关

我有一个表a,其中包含一个json列a.matchersa.matchers 是一个对象数组,每个对象都有属性 pattern 给定一个 inputString 我想获取至少有一个 matchers[].pattern 匹配 inputString LIKE '%{pattern}% 的所有行'

基本上(作为伪查询):

SELECT * 
FROM a 
WHERE 
    'inputStringABC' LIKE ANY('%' || json_array_elements(a.matchers)->>'pattern' || '%') 

这可能吗?

p.s.:PostgreSQL 版本为 9.6.3

编辑:更广泛的现状描述:

表a:

           Column            |            Type             |                   Modifiers                   | Storage  | Stats target | Description
------------------------------+-----------------------------+-----------------------------------------------+----------+--------------+-------------
 uuid                         | uuid                        | not null default uuid_generate_v4()           | plain    |              |
 matchers                     | json                        |                                               | extended |              |

列匹配器中的 JSON 结构:

[
    {
        pattern: string;
    }
]

示例用例:

我有一个字符串“Some trees看起来比其他树更好”以及表a中的以下行:

  • uuid:“123...”,匹配器:[{pattern:“trees”}]
  • uuid:“987...”,匹配器:[{pattern:“bees”},{pattern:“plants”}]

查询应返回 uuid “123...” 的行,因为 trees 出现在 “Some trees看起来比其他树更好”

编辑2:

感谢 s-man,最终查询对我有用

SELECT DISTINCT                                                  
    uuid,
    pattern
FROM (
    SELECT 
        *, 
        jsonb_array_elements(a.matchers)->>'pattern' as pattern  
    FROM a
) s
WHERE 
    'Some trees look nicer than others' LIKE '%' || pattern || '%'   

最佳答案

表格:

id   matchers
1    [{"abc": 1, "pattern": "ABC"}, {"pattern": "ABAB"}, {"cde": "FOO", "pattern": "AABB"}]
2    [{"pattern": "AB"}, {"cde": "BAR", "pattern": "CDE"}]
3    [{"abc": 2, "pattern": "CD"}, {"pattern": "FG"}] 

查询:

SELECT DISTINCT                                                  -- C
    id,
    matchers
FROM (
    SELECT 
        *, 
        jsonb_array_elements(a.matchers)->>'pattern' as pattern  -- A
    FROM a
) s
WHERE 
    pattern LIKE '%AB%'                                          -- B

A:jsonb_array_elements 将 json 数组扩展为每个数组元素一行。 ->> 运算符以文本形式给出每个数组元素包含的模式属性的值。

B:使用 LIKE 运算符过滤文本值

C:因为表已扩展,所以我们必须再次缩小它,因为我们只需要通过子查询在每一行中保存的原始列。

结果:

id   matchers
1    [{"abc": 1, "pattern": "ABC"}, {"pattern": "ABAB"}, {"cde": "FOO", "pattern": "AABB"}]
2    [{"pattern": "AB"}, {"cde": "BAR", "pattern": "CDE"}]

demo: db<>fiddle


如果您的列的类型是 json 而不是 jsonb,那么您当然必须使用 json_array_elements


编辑:在使问题更加清晰之后,发现该模式的用例是相反的。因此,将 WHERE 子句更改为:

即可达到预期结果
'long input string including pattern' LIKE '%' || pattern || '%'

Further reading

关于sql - PostgreSQL 与 json 数组中的模式反向 LIKE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52460966/

相关文章:

linux - 如何修改一个json值

python - Pandas:将 JSON 列表值拆分为新列

java - Json对象到pojo转换

sql - 将一串 ids 转换为一串等效名称

sql - postgresql 中缺少 block 号 0 的错误,我已经弄清楚哪个字段已损坏

mysql - 更新限制或类似的东西

sql - 存储 "Worked Hours"的正确数据类型是什么

当列包含 utf-8 字符时 MySQL 查询返回错误数据

mysql - 选择特定日期输入的所有记录 - MySQL

java - 在 liquibase 上用 JSON 内容重构数据库