Запрос с элементами зависит от другого - PullRequest
0 голосов
/ 23 октября 2018

Существует база данных Postgres, и таблица имеет три столбца.Структура данных находится во внешней системе, поэтому я не могу ее изменить.

Каждый объект представлен тремя строками (обозначается столбцом element_id - строки с одинаковым значением в этом столбце представляют один и тот же объект), дляпример:

key     value            element_id
-----------------------------------
status  active           1
name    exampleNameAAA   1
city    exampleCityAAA   1
status  inactive         2
name    exampleNameBBB   2
city    exampleCityBBB   2
status  inactive         3
name    exampleNameCCC   3
city    exampleCityCCC   3

В запросе я хочу поместить список некоторых имен, проверить, имеет ли значение строки с key столбец status в том же объекте статус «активный», и вернутьимя этого объекта, только если статус «активный».

Так что для этого примера в таблице базы данных есть три объекта.Я хочу добавить в запрос два «имени»:

a) exampleNameAAA

b) exampleNameCCC

, и результат должен быть: exampleNameAAA (потому чтоЯ запросил два объекта, и только один из них имеет значение active в строке status.

Ответы [ 3 ]

0 голосов
/ 23 октября 2018

Вы можете использовать запрос EXISTS:

select e1.*
from element e1
where (e1.key, e1.value)  in ( ('name', 'exampleNameAAA'), ('name', 'exampleNameCCC'))
and exists (select *
            from element e2
            where e2.element_id = e1.element_Id  
              and (e2.key, e2.value) = ('status', 'active'));

Онлайн пример: https://rextester.com/JOWED21150

0 голосов
/ 23 октября 2018

Мне нравится выражать это как:

SELECT MAX(t.value) FILTER (WHERE t.key = 'name') AS name
FROM t
GROUP BY t.element_id
HAVING MAX(t.value) FILTER (WHERE t.key = 'name') IN ('exampleNameAAA', 'exampleNameCCC') AND
       MAX(t.value) FILTER (WHERE t.key = 'status') = 'active';

Все это говорит о том, что решение exists, вероятно, более производительно в этом случае.Преимущество подхода агрегации состоит в том, что вы можете легко перенести дополнительные столбцы в select, например, город:

SELECT MAX(t.value) FILTER (WHERE t.key = 'name') AS name,
       MAX(t.value) FILTER (WHERE t.key = 'city') as city

(Примечание: key - это плохое имя для столбца, потому что этоключевое слово SQL.)

0 голосов
/ 23 октября 2018

В одном варианте используется агрегирование:

SELECT
    MAX(CASE WHEN "key" = 'name' THEN "value" END) AS name
FROM yourTable
GROUP BY element_id
HAVING
    MAX(CASE WHEN "key" = 'name' THEN "value" END) IN
        ('exampleNameAAA', 'exampleNameCCC') AND
    SUM(CASE WHEN "key" = 'status' AND "value" = 'active' THEN 1 ELSE 0 END) > 0;

name
exampleNameAAA

Демонстрация

Это сводный подход, в котором мы выделяем отдельные ключи и значения длякаждая element_id группа.

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