从postgres中的json数组列获取结果

时间:2017-07-12 13:10:27

标签: postgresql

我有PostgreSQL 9.5表(仪器)有2列instrument_id和user_maps,如下所示:

enter image description here

我想根据以下条件获取所有乐器:

  • 遍历user_maps中的每个json对象
  • 计算状态为Y,N或D的json对象的数量
  • 计数应该超过2个。

注意:user_maps是一个json对象数组,有2个字段status和userId

示例user_maps链接到instrument_id“I01”:

[
  {
    "status": "Y",
    "userId": "ZU201707120539150007"
  },
  {
    "status": "D",
    "userId": "ZU201707120540510008"
  },
  {
    "status": "I",
    "userId": "ZU201707120542540009"
  },
  {
    "status": "I",
    "userId": "ZU201707011725050001"
  },
  {
    "status": "Y",
    "userId": "ZU201707120552050013"
  }
]

仪器ID“I01”应该是最终结果。

另一个,示例user_maps链接到instrument_id“I02”:

[
  {
    "status": "I",
    "userId": "ZU201707120539150007"
  },
  {
    "status": "I",
    "userId": "ZU201707120540510008"
  },
  {
    "status": "I",
    "userId": "ZU201707120542540009"
  },
  {
    "status": "I",
    "userId": "ZU201707011725050001"
  },
  {
    "status": "Y",
    "userId": "ZU201707120552050013"
  }
]

仪器ID“I02”不应该出现在最终结果中因为它只有一个json具有状态(Y,N,D)。

1 个答案:

答案 0 :(得分:0)

如果我理解了您的要求,那么您就可以这样做:

-- This is just test dataset as you provided
WITH    test( instrument_id, user_maps ) AS (
            VALUES
                (   'I01'::text,
                    $$[
                      { "status": "Y", "userId": "ZU201707120539150007" },
                      { "status": "D", "userId": "ZU201707120540510008" },
                      { "status": "I", "userId": "ZU201707120542540009" },
                      { "status": "I", "userId": "ZU201707011725050001" },
                      { "status": "Y", "userId": "ZU201707120552050013" }
                    ]$$::jsonb ),
                (   'I02'::text,
                    $$[
                      { "status": "I", "userId": "ZU201707120539150007" },
                      { "status": "I", "userId": "ZU201707120540510008" },
                      { "status": "I", "userId": "ZU201707120542540009" },
                      { "status": "I", "userId": "ZU201707011725050001" },
                      { "status": "Y", "userId": "ZU201707120552050013" }
                    ]$$::jsonb )
        )
SELECT  t.instrument_id,
        count( u )
FROM    test t,
        jsonb_array_elements( user_maps ) u     -- does lateral join to get json array elements
WHERE   u -> 'status' ?| ARRAY['Y', 'N', 'D']   -- your search condition
GROUP BY 1
HAVING count( u ) > 2;                          -- the count condition you wanted

 -- This is the result of the query
 instrument_id | count
---------------+-------
 I01           |     3
(1 row)