使用jsonb

时间:2018-03-27 21:56:32

标签: sql json postgresql entity-attribute-value

我尝试使用Attribute - > Value表格来实施EAV模式,但不像jsonb中存储的标准方式值那样{"attrId":[values]}。它有助于轻松搜索请求,例如:

SELECT * FROM products p WHERE p.attributes @> "{1:[2]} AND p.attributes @> "{1:[4]}"

现在我想知道这是一个好方法,以及计算可用变量计数的有效方法,例如:

-p1- {"width":[1]} -p2- {"width":[2],"height":[3]} -p3- {"width":[1]}

输出

width: 1(计数2); 2(计数1)

height: 3(计数1)

选择width 2

width: 1(计数0); 2(计数1)

height:3(计数1)

1 个答案:

答案 0 :(得分:1)

“扁平比嵌套更好” - 蟒蛇的禅

我认为你最好使用简单的键/值对,并且在极少数情况下你有一个复杂的值,然后把它作为一个列表。但我没有看到那个用例。

以下是回答您问题的示例。它可以修改为使用你的结构,但让我们保持简单:

首先创建一个表并插入一些JSON:

# create table foo (a jsonb);
# insert into foo values ('{"a":"1", "b":"2"}');
# insert into foo values ('{"c":"3", "d":"4"}');
# insert into foo values ('{"e":"5", "a":"6"}');

以下是记录:

# select * from foo;
          a
----------------------
 {"a": "1", "b": "2"}
 {"c": "3", "d": "4"}
 {"a": "6", "e": "5"}
(3 rows)

以下是来自https://www.postgresql.org/docs/9.6/static/functions-json.html

的json_each_text()函数的输出
# select jsonb_each_text(a) from foo;
 jsonb_each_text
-----------------
 (a,1)
 (b,2)
 (c,3)
 (d,4)
 (a,6)
 (e,5)
(6 rows)

现在我们需要将它放在表表达式中,以便能够访问各个字段:

# with t1 as (select jsonb_each_text(a) as rec from foo) 
  select (rec).key, (rec).value from t1;

 key | value
-----+-------
 a   | 1
 b   | 2
 c   | 3
 d   | 4
 a   | 6
 e   | 5
(6 rows)

最后这里是一个带SUM函数的分组。请注意,数据库2x中的a键已正确求和。

# with t1 as (select jsonb_each_text(a) as rec from foo) 
  select (rec).key, sum((rec).value::int) from t1 group by (rec).key;

 key | sum
-----+-----
 c   |   3
 b   |   2
 a   |   7
 e   |   5
 d   |   4
(5 rows)

作为最后一点,(rec)周围有括号,因为否则会错误地将其视为表格,并会导致此错误:

ERROR:  missing FROM-clause entry for table "rec"