【问题标题】:Oracle JSON query甲骨文 JSON 查询
【发布时间】:2021-04-28 17:21:21
【问题描述】:

我有一个 JSON 列,它在 people 表上存储人们在他们访问过的国家所做的最佳活动......

{
  "countries": [
    {
      "name": "Ireland",
      "bestActivity": {
        "name": "Drinking"
      }
    },
    {
      "name": "Scotland",
      "bestActivity": {
        "name": "Dancing"
      }
    }
  ]
}

其他人可能是:

{
  "countries": [
    {
      "name": "Ireland",
      "bestActivity": {
        "name": "Football"
      }
        },
    {
      "name": "England",
      "bestActivity": {
        "name": "Golf"
      }
        }
  ]
}

我想选择所有访问过爱尔兰并且在爱尔兰饮酒活动最好的人,以及访问过苏格兰并且饮酒活动最好的人。

真的很挣扎。有什么建议吗?

【问题讨论】:

    标签: sql json oracle oracle12c


    【解决方案1】:

    您可以使用JSON_EXISTS 函数根据您描述的条件过滤您的表格。我使用您在问题中提供的 JSON 结构在下面构建了一个示例查询。

    WITH
        sample_table (first_name, json_col)
        AS
            (SELECT 'John', '{
         "countries": [
            { 
                "name": "Ireland",
                "bestActivity" : {
                     "name": "Drinking"
                 }, 
            },
            { 
                "name": "Scotland",
                "bestActivity" : {
                      "name": "Dancing"
                 }
            }
     }' FROM DUAL
             UNION ALL
             SELECT 'Jane', '{
         "countries": [
            { 
                "name": "Ireland",
                "bestActivity" : {
                     "name": "Football"
                 }, 
            },
            { 
                "name": "England",
                "bestActivity" : {
                      "name": "Golf"
                 }
            }
     }' FROM DUAL)
    SELECT *
      FROM sample_table s
     WHERE     JSON_EXISTS (s.json_col, '$.countries[*]?(@.name == "Scotland")')
           AND JSON_EXISTS (
                   s.json_col,
                   '$.countries[*]?(@.name == "Ireland" && @.bestActivity.name == "Drinking")');
    

    【讨论】:

      【解决方案2】:

      您可以使用JSON_TABLE() 函数,因为您的数据库版本是12c适用于所有子版本),例如

      SELECT first_name
        FROM t,   
        JSON_TABLE(jscol, '$.countries[*]' 
             COLUMNS ( 
                      country      VARCHAR2(90) PATH '$.name',  
                      bestActivity VARCHAR2(90) PATH '$.bestActivity.name'
                     )
                  )
       WHERE (country = 'Ireland' AND bestActivity = 'Drinking')
          OR  country = 'Scotland'
       GROUP BY first_name
       HAVING COUNT(*)>1
      

      Demo

      你可以使用JSON_EXISTS()函数是数据库版本是12cR2+这样的格式

      SELECT first_name
        FROM t
       WHERE JSON_EXISTS(jscol,
                          '$.countries?(@.name == "Ireland"
                                     && @.bestActivity.name == "Drinking")')
         AND JSON_EXISTS(jscol,                            
                          '$.countries?(@.name == "Scotland")');
      

      Demo

      请注意,当使用SQL*Plus 时,应在发出SET DEFINE OFF 后调用查询,以防止&& 操作数被解释为替换变量。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多