Я последовал за ответом Эрвина Брандштеттера на нахождение с использованием комбинаций атрибутов . У меня тоже есть похожая проблема, но с разницей.
Допустим, мои данные таковы:
CREATE TABLE tracks (id serial, data jsonb);
INSERT INTO tracks (id, data) VALUES
(1, '[{"artist": "Simple Plan", "title": "Welcome to My Life"}]')
, (2, '[{"artist": "Another Artist", "title": "Welcome to My Life"},
{"artist": "Simple Plan", "title": "Perfect", "awarded": "True"}]')
, (3, '[{"artist": "Another Artist", "title": "Welcome to My Life"},
{"artist": "Simple Plan", "title": "Perfect", "awarded": "True"},
{"artist": "Simple Plan", "title": "Perfect"}
]')
, (4, '[{"artist": "Another Artist", "title": "Welcome to My Life"},
{"artist": "Simple Plan", "title": "Perfect", "year": "2005"},
{"artist": "Simple Plan", "title": "Perfect", "awarded": "True"},
{"artist": "Simple Plan", "title": "Perfect"}
]');
Я также использую ту же индексацию: gin (data jsonb_path_ops)
Когда я запрашиваю:
SELECT * FROM tracks
WHERE data @> '[{"artist": "Simple Plan", "title": "Welcome to My Life"}]';
вернется 1, '[{"artist": "Simple Plan", "title": "Welcome to My Life"}]'
И когда я запрашиваю:
SELECT * FROM tracks
WHERE data @> '[{"artist": "Simple Plan", "title": "Perfect"}]';
вернется
(2, '[{"artist": "Another Artist", "title": "Welcome to My Life"},
{"artist": "Simple Plan", "title": "Perfect", "awarded": "True"}]')
,(3, '[{"artist": "Another Artist", "title": "Welcome to My Life"},
{"artist": "Simple Plan", "title": "Perfect", "awarded": "True"},
{"artist": "Simple Plan", "title": "Perfect"}
]')
,(4, '[{"artist": "Another Artist", "title": "Welcome to My Life"},
{"artist": "Simple Plan", "title": "Perfect", "year": "2005"},
{"artist": "Simple Plan", "title": "Perfect", "awarded": "True"},
{"artist": "Simple Plan", "title": "Perfect"}
]')
Теперь я хочу сделать что-то отличное от вышеупомянутой темы :
Хотите получить только часть json для каждого идентификатора, которая соответствует запросу, т.е. только элемент {"artist": "Simple Plan", "title": "Perfect"}
Хочется соответствовать только незарегистрированный титульный лист . Чтобы сэкономить место, я храню только «награжденный»: «True», если титул присуждается. В противном случае поле «награжден» отсутствует, что означает, что звание не было присвоено.
Выходные данные будут примерно такими:
(3, '[ {"artist": "Simple Plan", "title": "Perfect"}
]')
,(4, '[{"artist": "Simple Plan", "title": "Perfect", "year": "2005"},
{"artist": "Simple Plan", "title": "Perfect"}
]')
Для этого я пытался следовать Другой ответ Эрвина .
Но проблема в том, что id = 4 будет иметь две строки в результате, в то время как я хочу иметь одну запись для идентификатора .
Это достижимо?
Кроме того, поскольку у меня огромный набор данных, я буду применять LIMIT к числу результатов. Вероятно, эта информация не относится к этому вопросу. Я упомянул это потому, что в настоящее время я делаю запрос
SELECT * FROM tracks
WHERE data @> '[{"artist": "Simple Plan", "title": "Perfect"}]
LIMIT 20;
, а затем возвращаем результаты sql. Я проверяю, упоминается ли поле «награждено» или нет. Если присутствует поле «наград», я игнорирую этот элемент. Я понимаю, что это не эффективный способ выполнения запросов. Кроме того, поскольку я игнорирую элементы как часть постобработки, я получаю меньшее количество элементов.
Среда: я использую postgreSQL 10.
Надеюсь, теперь мой вопрос понятен.