如何在 SQL 中获取看起来像 JSON dict 的值?

Posted

技术标签:

【中文标题】如何在 SQL 中获取看起来像 JSON dict 的值?【英文标题】:How can I get values that looks like a JSON dict in SQL? 【发布时间】:2021-01-05 13:14:24 【问题描述】:

事情是这样的,我有一张这样的桌子:

col1        col2                                     col3
A           "0":10, "5":5, "15":3                  6
B           "5":30, "10":20, "15":10, "20":5       15
C           "0":30, "3":20, "8":10, "9":5          2
.
.
.

col2 基本上是一个等级(引号之间的数字)和一个等级; col3 是每个客户的排名(在 col1 中定义)。所以如果客户 A 排名 0-4,他的等级是 10,如果他排名 5-14,他的等级是 5,否则是 3。 我需要通过获取与 col3 中定义的等级相对应的等级来创建一个新列。

这是最终结果的样子:

col1        col2                                     col3    col4
A           "0":10, "5":5, "15":3                  5       5
B           "5":30, "10":20, "15":10, "20":5       13      20
C           "0":30, "3":20, "8":10, "9":5          2       30
.
.
.

有什么想法吗?我考虑过 split_part(),但我认为我无法完成这项工作,即使在很多情况下(不确定,想不出解决方案)。

【问题讨论】:

【参考方案1】:

您可能会发现以下方法很有用。 不幸的是,与 PostgreSQL(它基于)相比,Redshift 所需的功能更少。 这就是为什么我必须应用一些解决方法 - 表“number_sequence”,它用于从客户 JSON 中提取成绩。有必要使用客户 JSON 字典中提供的最高排名值的序列号填充此表。此外,由于我无法访问 Redshift,因此我仅在 PostgreSQL 中测试了该解决方案。因此,对 Redshift 环境进行一些定制可能是必要的。祝你好运! :)

CREATE TABLE number_sequence (
    num int
);

INSERT INTO number_sequence (num)
SELECT * FROM (VALUES
  (0),  (1),  (2),  (3),  (4),  (5),  (6),  (7),  (8),  (9),
  (10), (11), (12), (13), (14), (15), (16), (17), (18), (19),
  (20), (21), (22), (23), (24), (25), (26), (27), (28), (29)
) num_sec;

CREATE TABLE customer_rank_grade (
  col1 varchar,
  col2 varchar,
  col3 int
);

INSERT INTO customer_rank_grade (col1, col2, col3)
select * from
(values 
('A', '"0":10, "5":5, "15":3',            5),
('B', '"5":30, "10":20, "15":10, "20":5', 13),
('C', '"0":30, "3":20, "8":10, "9":5',    2)
) data;

WITH selected_rank as (
SELECT
  col1,
  col2,
  col3,
  json_extract_path_text(col2::json, num::varchar) as col4,
  ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY num DESC) as row_num
FROM number_sequence
JOIN customer_rank_grade
  ON json_extract_path_text(col2::json, num::varchar) IS NOT NULL
WHERE num <= col3
)
SELECT 
  col1, col2, col3, col4
FROM selected_rank
WHERE row_num = 1
ORDER BY col1;

【讨论】:

以上是关于如何在 SQL 中获取看起来像 JSON dict 的值?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Python 字典保存为 NodeJS 字典? [复制]

如何将 Python 字典保存为 NodeJS 字典? [复制]

Pyspark 将 JSON 读取为 dict 或 struct 而不是数据帧/RDD

Django模板如何使用标签和模板过滤器从json dict中获取数据

如何在json中获取评级数组

如何解析... dict的字典列表到数据帧?