Запрос, чтобы определить, содержит ли значение JSON указанный атрибут - PullRequest
0 голосов
/ 11 апреля 2020

Я хочу запросить таблицу, которая содержит JSON данных. Данные столбца детализация в таблице детализации приведены ниже.

id     | 1

detail | {
   myCompany: [{ email: 'company@company.com', inProfit: true }],
   myData: [
      { email: 'example@example.com', personalUse: true },
      { email: 'test@test.com', personalUse: false },
   ],
};

Значение столбца JSON подробно выглядит следующим образом

{
   "myCompany":[
      {
         "email":"company@company.com",
         "inProfit":true
      }
   ],
   "myData":[
      {
         "email":"example@example.com",
         "personalUse":true
      },
      {
         "email":"test@test.com",
         "personalUse":false
      }
   ]
} 

Я хочу запрос, который извлекает идентификатор , если переданный адрес электронной почты присутствует в myData и имеет true значение для personalUse . Запрос не возвращает id , если переданное письмо присутствует, но не имеет personalUse как true .

Я использовал ниже два запроса, но он вернет id для обоих случаев.

SELECT id 
FROM details 
WHERE (detail->'myData')::JSONB @> '[{"email": "example@example.com"}, 
                                     {"personalUse": true}]'::JSONB;

SELECT id 
FROM details 
WHERE (detail->'myData')::JSONB @> '[{"email": "test@test.com"}, 
                                     {"personalUse": true}]'::JSONB;

Ожидаемый вывод: он должен возвращать id для первого запроса и не возвращать id для второго.

Вы можете использовать ниже запросы, чтобы попробовать его локально.

CREATE TABLE details (id bigserial primary key, detail json not null);

INSERT INTO details (detail) 
VALUES 
  ('{"myCompany":[{"email":"company@company.com", "inProfit":true } ],  
     "myData":[{"email":"example@example.com", "personalUse":true }, 
               {"email":"test@test.com", "personalUse":false } ] }');

1 Ответ

1 голос
/ 11 апреля 2020

Вы сравниваете массив с двумя элементами (каждый с одним ключом) в ваших запросах, а не массив с одним элементом, который содержит два ключа.

Массив содержит {"email": "test@test.com", "personalUse": true} данных), и это нечто иное, чем {"email": "example@example.com"}, {"personalUse": true} - это значение, с которым вы сравниваете.

В ваших запросах первый json ключ / значение Пара (с адресом электронной почты) совпадает в обоих значениях в таблице, а оператор содержит @> проверяет только хотя бы одно совпадение.

Следующие запросы работают должным образом:

SELECT id 
FROM details 
WHERE detail -> 'myData' @> '[{"email": "test@test.com", "personalUse": true}]';

SELECT id 
FROM details 
WHERE detail -> 'myData' @> '[{"email": "example@example.com", "personalUse": true}]';

(я удалил приведение к jsonb для лучшей читаемости)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...