【问题标题】:Parse JSON in Postgres在 Postgres 中解析 JSON
【发布时间】:2017-10-30 20:02:06
【问题描述】:

我将以下 JSON 存储在 Postgres 表中名为“数据”的 JSONB 列中:

{"resource":"boxscore","parameters":{"GameID":"0021700079","StartPeriod":0,"EndPeriod":0,"StartRange":0,"EndRange":0,"RangeType":0},"resultSets":[{"name":"PlayerStats","headers":["GAME_ID","TEAM_ID","TEAM_ABBREVIATION","TEAM_CITY","PLAYER_ID","PLAYER_NAME","START_POSITION","COMMENT","MIN","FGM","FGA","FG_PCT","FG3M","FG3A","FG3_PCT","FTM","FTA","FT_PCT","OREB","DREB","REB","AST","STL","BLK","TO","PF","PTS","PLUS_MINUS"],"rowSet":[["0021700079",1610612760,"OKC","Oklahoma City",202331,"Paul George","F","","28:43",8,15,0.533,4,5,0.800,0,0,0.000,1,4,5,0,4,0,3,2,20,20.000],["0021700079",1610612760,"OKC","Oklahoma City",2546,"Carmelo Anthony","F","","27:41",7,16,0.438,5,9,0.556,2,2,1.000,0,5,5,2,0,0,0,2,21,26.000],["0021700079",1610612760,"OKC","Oklahoma City",203500,"Steven Adams","C","","28:11",6,10,0.600,0,0,0.000,0,0,0.000,5,3,8,2,1,1,1,0,12,23.000],["0021700079",1610612760,"OKC","Oklahoma City",203460,"Andre Roberson","G","","20:22",2,2,1.000,1,1,1.000,0,0,0.000,1,0,1,1,0,1,0,2,5,21.000],["0021700079",1610612760,"OKC","Oklahoma City",201566,"Russell Westbrook","G","","28:25",5,13,0.385,0,2,0.000,2,3,0.667,2,11,13,13,2,0,2,2,12,26.000],["0021700079",1610612760,"OKC","Oklahoma City",203924,"Jerami Grant","","","23:00",2,4,0.500,0,1,0.000,2,3,0.667,0,4,4,1,3,2,1,2,6,2.000],["0021700079",1610612760,"OKC","Oklahoma City",203518,"Alex Abrines","","","18:09",2,8,0.250,1,5,0.200,0,0,0.000,0,2,2,1,2,0,1,2,5,-1.000],["0021700079",1610612760,"OKC","Oklahoma City",101109,"Raymond Felton","","","20:24",3,8,0.375,2,4,0.500,4,6,0.667,1,7,8,3,2,1,1,1,12,7.000],["0021700079",1610612760,"OKC","Oklahoma City",202335,"Patrick Patterson","","","15:01",1,5,0.200,0,4,0.000,0,0,0.000,1,1,2,0,2,0,1,0,2,2.000],["0021700079",1610612760,"OKC","Oklahoma City",203962,"Josh Huestis","","","17:02",1,5,0.200,0,3,0.000,0,0,0.000,0,2,2,1,0,1,1,2,2,13.000],["0021700079",1610612760,"OKC","Oklahoma City",1628390,"Terrance Ferguson","","","4:48",1,1,1.000,0,0,0.000,0,0,0.000,0,1,1,0,0,0,0,2,2,7.000],["0021700079",1610612760,"OKC","Oklahoma City",2555,"Nick Collison","","","4:48",0,0,0.000,0,0,0.000,0,0,0.000,0,0,0,1,0,0,0,0,0,7.000],["0021700079",1610612760,"OKC","Oklahoma City",1626177,"Dakari Johnson","","","3:26",1,1,1.000,0,0,0.000,0,0,0.000,0,1,1,3,0,2,0,0,2,7.000],["0021700079",1610612741,"CHI","Chicago",1627835,"Paul Zipser","F","","17:05",1,5,0.200,1,3,0.333,0,0,0.000,1,2,3,0,1,0,3,1,3,-18.000],["0021700079",1610612741,"CHI","Chicago",1628374,"Lauri Markkanen","F","","27:54",3,7,0.429,3,6,0.500,6,6,1.000,3,5,8,1,0,1,0,1,15,-17.000],["0021700079",1610612741,"CHI","Chicago",201577,"Robin Lopez","C","","25:22",4,9,0.444,0,0,0.000,2,2,1.000,1,2,3,2,0,2,1,1,10,-13.000],["0021700079",1610612741,"CHI","Chicago",203200,"Justin Holiday","G","","31:39",4,16,0.250,3,10,0.300,0,1,0.000,2,3,5,2,1,0,4,1,11,-18.000],["0021700079",1610612741,"CHI","Chicago",1626170,"Jerian Grant","G","","21:00",0,7,0.000,0,6,0.000,2,3,0.667,1,1,2,4,1,0,0,1,2,-17.000],["0021700079",1610612741,"CHI","Chicago",1627756,"Denzel Valentine","","","30:55",3,12,0.250,2,5,0.400,0,0,0.000,3,6,9,3,1,0,3,2,8,-14.000],["0021700079",1610612741,"CHI","Chicago",202347,"Quincy Pondexter","","","20:06",1,7,0.143,1,7,0.143,3,4,0.750,0,3,3,0,0,0,3,3,6,-15.000],["0021700079",1610612741,"CHI","Chicago",1627739,"Kris Dunn","","","22:12",4,9,0.444,0,0,0.000,0,0,0.000,1,3,4,3,3,1,4,5,8,-8.000],["0021700079",1610612741,"CHI","Chicago",1626245,"Cristiano Felicio","","","22:38",1,2,0.500,0,0,0.000,0,0,0.000,0,8,8,0,0,1,1,0,2,-19.000],["0021700079",1610612741,"CHI","Chicago",1628021,"David Nwaba","","","16:21",1,3,0.333,0,0,0.000,2,4,0.500,0,2,2,0,2,0,0,1,4,-14.000],["0021700079",1610612741,"CHI","Chicago",1627770,"Kay Felder","","","4:48",0,1,0.000,0,0,0.000,0,0,0.000,0,0,0,1,0,0,0,0,0,-7.000]]},{"name":"TeamStats","headers":["GAME_ID","TEAM_ID","TEAM_NAME","TEAM_ABBREVIATION","TEAM_CITY","MIN","FGM","FGA","FG_PCT","FG3M","FG3A","FG3_PCT","FTM","FTA","FT_PCT","OREB","DREB","REB","AST","STL","BLK","TO","PF","PTS","PLUS_MINUS"],"rowSet":[["0021700079",1610612760,"Thunder","OKC","Oklahoma City","240:00",39,88,0.443,13,34,0.382,10,14,0.714,11,41,52,28,16,8,11,17,101,32.000000],["0021700079",1610612741,"Bulls","CHI","Chicago","240:00",22,78,0.282,10,37,0.270,15,20,0.750,12,35,47,16,9,5,19,16,69,-32.000000]]},{"name":"TeamStarterBenchStats","headers":["GAME_ID","TEAM_ID","TEAM_NAME","TEAM_ABBREVIATION","TEAM_CITY","STARTERS_BENCH","MIN","FGM","FGA","FG_PCT","FG3M","FG3A","FG3_PCT","FTM","FTA","FT_PCT","OREB","DREB","REB","AST","STL","BLK","TO","PF","PTS"],"rowSet":[["0021700079",1610612760,"Thunder","OKC","Oklahoma City","Starters","133:22",28,56,0.500,10,17,0.588,4,5,0.800,9,23,32,18,7,2,6,8,70],["0021700079",1610612760,"Thunder","OKC","Oklahoma City","Bench","106:38",11,32,0.344,3,17,0.176,6,9,0.667,2,18,20,10,9,6,5,9,31],["0021700079",1610612741,"Bulls","CHI","Chicago","Starters","123:00",12,44,0.273,7,25,0.280,10,12,0.833,8,13,21,9,3,3,8,5,41],["0021700079",1610612741,"Bulls","CHI","Chicago","Bench","117:00",10,34,0.294,3,12,0.250,5,8,0.625,4,22,26,7,6,2,11,11,28]]}]}

我需要对其进行解析以提取个人球员和球队的得分统计数据,然后将它们放在另一个表格中,每个球员一行,所有不同的统计数据都放在列中。例如,决赛桌应如下所示:

Player           | PTS | REB | AST | etc....
Paul George      | 20  |  5  |  0  | etc....
Carmelo Anthony  | 21  |  5  |  2  | etc....

但是,这些值看起来好像存储在列表中。如何利用 JSONB 函数解析这些数据点?我已尝试查看 Postgres 官方文档,但无法找到以我需要的方式专门提取这些数据的方法。

我通过 Python 将数据插入 Postgres 数据库。因此,如果先在 Python 中解析数据并将其传输到 Postgres 更容易/更明智,请告诉我。

【问题讨论】:

    标签: json postgresql jsonb


    【解决方案1】:

    手动解析所有这些会很乏味,但这是最明显的解决方案:

    SELECT
      rowSet -> 0 AS "GAME_ID",
      rowSet -> 1 AS "TEAM_ID",
      rowSet -> 2 AS "TEAM_ABBREVIATION",
      rowSet -> 3 AS "TEAM_CITY",
      rowSet -> 4 AS "PLAYER_ID",
      rowSet -> 5 AS "PLAYER_NAME",
      rowSet -> 6 AS "START_POSITION",
      rowSet -> 7 AS "COMMENT",
      rowSet -> 8 AS "MIN",
      rowSet -> 9 AS "FGM",
      rowSet -> 10 AS "FGA",
      rowSet -> 11 AS "FG_PCT",
      rowSet -> 12 AS "FG3M",
      rowSet -> 13 AS "FG3A",
      rowSet -> 14 AS "FG3_PCT",
      rowSet -> 15 AS "FTM",
      rowSet -> 16 AS "FTA",
      rowSet -> 17 AS "FT_PCT",
      rowSet -> 18 AS "OREB",
      rowSet -> 19 AS "DREB",
      rowSet -> 20 AS "REB",
      rowSet -> 21 AS "AST",
      rowSet -> 22 AS "STL",
      rowSet -> 23 AS "BLK",
      rowSet -> 24 AS "TO",
      rowSet -> 25 AS "PF",
      rowSet -> 26 AS "PTS",
      rowSet -> 27 AS "PLUS_MINUS"
      FROM
      (
        SELECT
          JSONB_ARRAY_ELEMENTS(resultSets -> 'rowSet') AS rowSet
        FROM
          (
            SELECT
              JSONB_ARRAY_ELEMENTS(data -> 'resultSets') AS resultSets -- Get individual players
              FROM
              (
              SELECT
                '{"resource":"boxscore","parameters":{"GameID":"0021700079","StartPeriod":0,"EndPeriod":0,"StartRange":0,"EndRange":0,"RangeType":0},"resultSets":[{"name":"PlayerStats","headers":["GAME_ID","TEAM_ID","TEAM_ABBREVIATION","TEAM_CITY","PLAYER_ID","PLAYER_NAME","START_POSITION","COMMENT","MIN","FGM","FGA","FG_PCT","FG3M","FG3A","FG3_PCT","FTM","FTA","FT_PCT","OREB","DREB","REB","AST","STL","BLK","TO","PF","PTS","PLUS_MINUS"],"rowSet":[["0021700079",1610612760,"OKC","Oklahoma City",202331,"Paul George","F","","28:43",8,15,0.533,4,5,0.800,0,0,0.000,1,4,5,0,4,0,3,2,20,20.000],["0021700079",1610612760,"OKC","Oklahoma City",2546,"Carmelo Anthony","F","","27:41",7,16,0.438,5,9,0.556,2,2,1.000,0,5,5,2,0,0,0,2,21,26.000],["0021700079",1610612760,"OKC","Oklahoma City",203500,"Steven Adams","C","","28:11",6,10,0.600,0,0,0.000,0,0,0.000,5,3,8,2,1,1,1,0,12,23.000],["0021700079",1610612760,"OKC","Oklahoma City",203460,"Andre Roberson","G","","20:22",2,2,1.000,1,1,1.000,0,0,0.000,1,0,1,1,0,1,0,2,5,21.000],["0021700079",1610612760,"OKC","Oklahoma City",201566,"Russell Westbrook","G","","28:25",5,13,0.385,0,2,0.000,2,3,0.667,2,11,13,13,2,0,2,2,12,26.000],["0021700079",1610612760,"OKC","Oklahoma City",203924,"Jerami Grant","","","23:00",2,4,0.500,0,1,0.000,2,3,0.667,0,4,4,1,3,2,1,2,6,2.000],["0021700079",1610612760,"OKC","Oklahoma City",203518,"Alex Abrines","","","18:09",2,8,0.250,1,5,0.200,0,0,0.000,0,2,2,1,2,0,1,2,5,-1.000],["0021700079",1610612760,"OKC","Oklahoma City",101109,"Raymond Felton","","","20:24",3,8,0.375,2,4,0.500,4,6,0.667,1,7,8,3,2,1,1,1,12,7.000],["0021700079",1610612760,"OKC","Oklahoma City",202335,"Patrick Patterson","","","15:01",1,5,0.200,0,4,0.000,0,0,0.000,1,1,2,0,2,0,1,0,2,2.000],["0021700079",1610612760,"OKC","Oklahoma City",203962,"Josh Huestis","","","17:02",1,5,0.200,0,3,0.000,0,0,0.000,0,2,2,1,0,1,1,2,2,13.000],["0021700079",1610612760,"OKC","Oklahoma City",1628390,"Terrance Ferguson","","","4:48",1,1,1.000,0,0,0.000,0,0,0.000,0,1,1,0,0,0,0,2,2,7.000],["0021700079",1610612760,"OKC","Oklahoma City",2555,"Nick Collison","","","4:48",0,0,0.000,0,0,0.000,0,0,0.000,0,0,0,1,0,0,0,0,0,7.000],["0021700079",1610612760,"OKC","Oklahoma City",1626177,"Dakari Johnson","","","3:26",1,1,1.000,0,0,0.000,0,0,0.000,0,1,1,3,0,2,0,0,2,7.000],["0021700079",1610612741,"CHI","Chicago",1627835,"Paul Zipser","F","","17:05",1,5,0.200,1,3,0.333,0,0,0.000,1,2,3,0,1,0,3,1,3,-18.000],["0021700079",1610612741,"CHI","Chicago",1628374,"Lauri Markkanen","F","","27:54",3,7,0.429,3,6,0.500,6,6,1.000,3,5,8,1,0,1,0,1,15,-17.000],["0021700079",1610612741,"CHI","Chicago",201577,"Robin Lopez","C","","25:22",4,9,0.444,0,0,0.000,2,2,1.000,1,2,3,2,0,2,1,1,10,-13.000],["0021700079",1610612741,"CHI","Chicago",203200,"Justin Holiday","G","","31:39",4,16,0.250,3,10,0.300,0,1,0.000,2,3,5,2,1,0,4,1,11,-18.000],["0021700079",1610612741,"CHI","Chicago",1626170,"Jerian Grant","G","","21:00",0,7,0.000,0,6,0.000,2,3,0.667,1,1,2,4,1,0,0,1,2,-17.000],["0021700079",1610612741,"CHI","Chicago",1627756,"Denzel Valentine","","","30:55",3,12,0.250,2,5,0.400,0,0,0.000,3,6,9,3,1,0,3,2,8,-14.000],["0021700079",1610612741,"CHI","Chicago",202347,"Quincy Pondexter","","","20:06",1,7,0.143,1,7,0.143,3,4,0.750,0,3,3,0,0,0,3,3,6,-15.000],["0021700079",1610612741,"CHI","Chicago",1627739,"Kris Dunn","","","22:12",4,9,0.444,0,0,0.000,0,0,0.000,1,3,4,3,3,1,4,5,8,-8.000],["0021700079",1610612741,"CHI","Chicago",1626245,"Cristiano Felicio","","","22:38",1,2,0.500,0,0,0.000,0,0,0.000,0,8,8,0,0,1,1,0,2,-19.000],["0021700079",1610612741,"CHI","Chicago",1628021,"David Nwaba","","","16:21",1,3,0.333,0,0,0.000,2,4,0.500,0,2,2,0,2,0,0,1,4,-14.000],["0021700079",1610612741,"CHI","Chicago",1627770,"Kay Felder","","","4:48",0,1,0.000,0,0,0.000,0,0,0.000,0,0,0,1,0,0,0,0,0,-7.000]]},{"name":"TeamStats","headers":["GAME_ID","TEAM_ID","TEAM_NAME","TEAM_ABBREVIATION","TEAM_CITY","MIN","FGM","FGA","FG_PCT","FG3M","FG3A","FG3_PCT","FTM","FTA","FT_PCT","OREB","DREB","REB","AST","STL","BLK","TO","PF","PTS","PLUS_MINUS"],"rowSet":[["0021700079",1610612760,"Thunder","OKC","Oklahoma City","240:00",39,88,0.443,13,34,0.382,10,14,0.714,11,41,52,28,16,8,11,17,101,32.000000],["0021700079",1610612741,"Bulls","CHI","Chicago","240:00",22,78,0.282,10,37,0.270,15,20,0.750,12,35,47,16,9,5,19,16,69,-32.000000]]},{"name":"TeamStarterBenchStats","headers":["GAME_ID","TEAM_ID","TEAM_NAME","TEAM_ABBREVIATION","TEAM_CITY","STARTERS_BENCH","MIN","FGM","FGA","FG_PCT","FG3M","FG3A","FG3_PCT","FTM","FTA","FT_PCT","OREB","DREB","REB","AST","STL","BLK","TO","PF","PTS"],"rowSet":[["0021700079",1610612760,"Thunder","OKC","Oklahoma City","Starters","133:22",28,56,0.500,10,17,0.588,4,5,0.800,9,23,32,18,7,2,6,8,70],["0021700079",1610612760,"Thunder","OKC","Oklahoma City","Bench","106:38",11,32,0.344,3,17,0.176,6,9,0.667,2,18,20,10,9,6,5,9,31],["0021700079",1610612741,"Bulls","CHI","Chicago","Starters","123:00",12,44,0.273,7,25,0.280,10,12,0.833,8,13,21,9,3,3,8,5,41],["0021700079",1610612741,"Bulls","CHI","Chicago","Bench","117:00",10,34,0.294,3,12,0.250,5,8,0.625,4,22,26,7,6,2,11,11,28]]}]}'::JSONB AS data
              ) _data
          ) _result
      ) _row
    

    您有一个不错的 JSON 数据集,其中包含 {资源、参数、结果集}。我最关心结果集,因为它包含玩家信息。这个未经修改的数据集我称之为_data。

    数据包含结果集。 resultSets 是一个数组,我想将该数组作为单独的行展开。

    JSONB_ARRAY_ELEMENTS(data -> 'resultSets')
    

    再看结构,你甚至不需要散布这个物体。 0 索引包含 PlayerStats 信息。因此,或者,您可以将其替换为:

    data -> 'resultSets' -> 0 AS resultSets 
    

    resultSets 包含行集。 rowSets 将所有玩家信息作为一个数组。这些数据再次分散到单独的行中。

    JSONB_ARRAY_ELEMENTS(resultSets -> 'rowSet')
    

    现在,您在每一行都有一个 JSONB 数组对象,其中包含称为 rowSet 的所有用户信息。您可以通过数组索引手动选择每一列来显示它们。

    rowSet -> 0 AS "GAME_ID"
    

    您可以在尝试解析 JSON 之前将其格式化为更易读的格式。

    【讨论】:

    • 我不确定你在那里做了什么,但效果很好。你能添加一个简短的解释它是如何工作的吗?
    • 我添加了解释。您可以自己尝试使用 JSON 对象。结帐postgresql.org/docs/current/static/functions-json.html 以获取您可以用它做什么的列表。
    • 是的,我在发表评论后这样做了。很酷的东西。
    猜你喜欢
    • 1970-01-01
    • 2014-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-21
    • 1970-01-01
    • 2012-08-11
    • 1970-01-01
    相关资源
    最近更新 更多