Sql 使用postgres筛选jsonb上的数据

Sql 使用postgres筛选jsonb上的数据,sql,postgresql,jsonb,Sql,Postgresql,Jsonb,假设你有一个网站,人们在那里发布他们的广告。因此,每个广告都有一些选定的属性,例如汽车有不同的发动机类型、齿轮、颜色等。这些属性是用户在提交列表之前选择的。 我将所选属性以jsonb格式存储在listings表中,请查看数据列: 因此,每个列表都包含如下数据: { "properties":[ { "id":"1", "value_id":"1" }, { "id":"2", "v

假设你有一个网站,人们在那里发布他们的广告。因此,每个广告都有一些选定的属性,例如汽车有不同的发动机类型、齿轮、颜色等。这些属性是用户在提交列表之前选择的。 我将所选属性以jsonb格式存储在listings表中,请查看数据列:

因此,每个列表都包含如下数据:

{
   "properties":[
      {
         "id":"1",
         "value_id":"1"
      },
      {
         "id":"2",
         "value_id":"5"
      },
      {
         "id":"3",
         "value_id":"9"
      },
      {
         "id":"4",
         "value":"2.0"
      },
      {
         "id":"7",
         "value":"2017"
      },
      {
         "id":"6",
         "value":"180.000"
      }
   ]
}
现在的问题是:

1如何根据json中的id和值筛选列表?例如,显示id=2且其值为5、id=3且其值为9的列表,依此类推。我不需要或,我需要和。因此,按多个id和值筛选数据


2第一点+比较id和大于或小于的值的能力。

回答第一点,这可能是我第一次使用jsonb[]:

对于第二个要求,它不会那么短,因为您需要比较并解析json:

t=# with c(a,j) as (values(18,'{
   "properties":[
      {
         "id":"1",
         "value_id":"1"
      },
      {
         "id":"2",
         "value_id":"5"
      },
      {
         "id":"3",
         "value_id":"9"
      },
      {
         "id":"4",
         "value":"2.0"
      },
      {
         "id":"7",
         "value":"2017"
      },
      {
         "id":"6",
         "value":"180.000"
      }
   ]
}'::jsonb), (19,'{"properties":[{"id": "1", "value_id": "1"}]}'))
, m as (select a, jb.value->>'id' id,jb.value->>'value_id' value_id from c, jsonb_array_elements(j->'properties') jb)
, n as (select m.*, count(1) over (partition by m.a)
from m
join c on c.a = m.a and ((id::int >= 1 and value_id::int <2) or (id::int >2 and value_id::int <= 9)))
select distinct a from n
where count > 1;
 a
----
 18
(1 row)

使用或获取可能的行,然后检查是否满足示例中的所有或条件的基本思想,看起来您正在jsonb中存储应该是单独表的内容。@Justinas Marozas,在单独的表中,我有这些属性的翻译和其他元数据。这是因为该网站有多种语言。我确实将这些值和id连接到另一个表中,但为什么要对这个具有规则结构的数据使用jsonb呢?为什么不使用一个单独的三列表来完成FKs?甚至是一个类似jsonb的数组['{id:1,value_id:1}'::jsonb,{id:2,value_id:5}',…]?是的,这不是一个简短的查询。在我的研究之后,我想我会同意上面的其他评论,最好为值和键创建一个单独的表,就是这样。更简单-更好。显然,创建表而不是将其数据保存在jsonb中是更好的主意:我是在回答你的问题-如何查询它,而不是解决规范化问题
t=# with c(a,j) as (values(18,'{
   "properties":[
      {
         "id":"1",
         "value_id":"1"
      },
      {
         "id":"2",
         "value_id":"5"
      },
      {
         "id":"3",
         "value_id":"9"
      },
      {
         "id":"4",
         "value":"2.0"
      },
      {
         "id":"7",
         "value":"2017"
      },
      {
         "id":"6",
         "value":"180.000"
      }
   ]
}'::jsonb), (19,'{"properties":[{"id": "1", "value_id": "1"}]}'))
, m as (select a, jb.value->>'id' id,jb.value->>'value_id' value_id from c, jsonb_array_elements(j->'properties') jb)
, n as (select m.*, count(1) over (partition by m.a)
from m
join c on c.a = m.a and ((id::int >= 1 and value_id::int <2) or (id::int >2 and value_id::int <= 9)))
select distinct a from n
where count > 1;
 a
----
 18
(1 row)