我有这个 Postgres 9.6 表定义:
CREATE TABLE research (
id int,
data jsonb
);
Run Code Online (Sandbox Code Playgroud)
并在其中包含以下示例数据
id |data
---|--------------------------------------------------------
1 |{"name": "Sim Ltd", "sector": "business", "personnel": {"headcount": {"total": 100, "male": 50, "female": 50}}}
2 |{"name": "EcoSmart", "sector": "business", "personnel": {"headcount": {"total": 500, "male": 460, "female": 40}}}
3 |{"name": "HIDN", "sector": "government", "personnel": {"headcount": {"total": 431, "male": 121, "female": 310}}}
4 |{"name": "RevDev", "sector": "government", "personnel": {"headcount": {"total": 15, "male": 10, "female": 5}}}
5 |{"name": "NEFPAN", "sector": "non-profit", "personnel": {"headcount": {"total": 5, "male": 4, "female": 1}}}
Run Code Online (Sandbox Code Playgroud)
我想得到 DISTINCT 部门的 COUNT 和 DISTINCT 部门的男性和女性总数的总和。我想要这样的结果:
Sector |Count |Total |Male |Female
------------|-------|-------|-------|--------
business |2 |600 |510 |90
government |2 |446 |131 |315
non-profit |1 |5 |4 |1
Run Code Online (Sandbox Code Playgroud)
如果有人能指导我为它编写 SQL,将不胜感激。我正在使用 Postgres 9.6。谢谢
joa*_*olo 11
你可以只使用:
SELECT
data->>'sector' AS "Sector",
count(data->>'sector') AS "Count",
sum((data->'personnel'->'headcount'->>'total')::integer) AS "Total",
sum((data->'personnel'->'headcount'->>'male')::integer) AS "Male",
sum((data->'personnel'->'headcount'->>'female')::integer) AS "Female"
FROM
research
GROUP BY
data->>'sector'
ORDER BY
data->>'sector' ;
Run Code Online (Sandbox Code Playgroud)
您使用两个PostgreSQLJSONB运算符:
jsonb -> field => gets the field out of the json(b), returning a json(b) object
jsonb ->> field => gets the field out of the json(b), returning it as text
Run Code Online (Sandbox Code Playgroud)
你只会得到:
部门 | 计数 | 总计 | 男 | 女性 :--------- | ----: | ----: | ---: | -----: 业务 | 2 | 600 | 510 | 90 政府| 2 | 第446话 131 | 315 非盈利 | 1 | 5 | 4 | 1
但是,对于这种数据结构完美的场景,如果使用规范化 SQL会更有意义。这将是您的表的结构(没有冗余数据):
CREATE TABLE normalized_research
(
id integer PRIMARY KEY,
name text,
sector text,
male_headcount integer,
female_headcount integer
) ;
Run Code Online (Sandbox Code Playgroud)
这是您填写的方式:
INSERT INTO
normalized_research
(id, name, sector, male_headcount, female_headcount)
SELECT
id,
data->>'name',
data->>'sector',
(data->'personnel'->'headcount'->>'male')::integer,
(data->'personnel'->'headcount'->>'female')::integer
FROM
research ;
Run Code Online (Sandbox Code Playgroud)
这是您将要进行的(更好、更快、更安全)的查询:
SELECT
sector AS "Sector",
count(sector) AS "Count",
sum(male_headcount)+sum(female_headcount) AS "Total",
sum(male_headcount) AS "Male",
sum(female_headcount) AS "Female"
FROM
normalized_research
GROUP BY
sector
ORDER BY
sector ;
Run Code Online (Sandbox Code Playgroud)
......这会给你完全相同的结果。
你可以在这个 DBFiddle找到所有的逻辑
JSON 主要是为了在 Web 服务和 Web 消费者(通常用 JavaScript 编写)之间传输和交换数据(通过 Ajax)而发明的。
引用JSON.org:
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。人类很容易阅读和写作。机器很容易解析和生成。它基于 JavaScript 编程语言标准 ECMA-262 第 3 版 - 1999 年 12 月的一个子集。
(强调我的)
它非常适合其最初的用途。但它并没有被设计为一种在数据库中存储数据的方式。不知何故,这是事后的想法,因为您可以非常轻松地做到这一点。您可以将 JSON 存储为文本,并且您已经可以使用任何数据库,即使它不知道 JSON。
在某些场合(通常链接到非常可变的数据结构,以及事先不知道的数据结构)它是一个不错的选择。但是,当您的数据结构完美时,您的架构(=结构)是众所周知的并且不需要很大的灵活性:普通的旧规范化 SQL 是更好的选择:您拥有数据类型安全性、一致性、更容易索引,参照完整性,更快的访问,...
| 归档时间: |
|
| 查看次数: |
9687 次 |
| 最近记录: |