У меня есть таблица, в которой хранятся параметры конфигурации приложения, например:
setName | key | value
----------------------------------
dev | FooEnabled | true
dev | BarEnabled | true
qa | FooEnabled | false
...etc...
Каждый параметр, комбинация ключ / значение, принадлежит определенному «набору конфигурации». Легко выбрать все свойства в определенном наборе:
SELECT p Parameter p WHERE p.setName = :name
Так что, если бы я хотел, чтобы все параметры в наборе конфигурации назывались "dev"
, я бы вернулся
dev | FooEnabled | true
dev | BarEnabled | true
Теперь я хотел бы выбрать объединение двух наборов:
SELECT p Parameter p WHERE p.setName = :name1 OR p.setName = :name2
... но исключить строки с дублирующимися ключами, задав свойства в наборе с name1
более высоким приоритетом, чем свойства в наборе с name2
. Если name1
было "qa"
, а name2
было "dev"
, то это вернуло бы
dev | FooEnabled | true
qa | BarEnabled | false
Чтобы уточнить, запрос должен ВЫБРАТЬ:
- Каждое свойство из множества с именем
name2
, кроме случаев, когда ...
- В наборе есть свойство с тем же ключом с именем
name1
, в этом случае ...
- Выберите строку с помощью
setName = :name1
вместо строки с помощью setName = :name2
Какой JPQL-запрос сделает это эффективно? Если COALESCE
работает с нескалярными значениями, то я представляю, что что-то подобное может работать:
SELECT
COALESCE(x, y)
FROM Property x, Property y
WHERE
x.setName = :name1 AND
y.setName = :name2 AND
x.key = y.key
, но COALESCE
принимает только скалярные значения. Есть идеи?
Другие запросы предприняты / не выполнены:
SELECT
CASE
WHEN (NOT EXISTS (SELECT y FROM Property y WHERE y.setName = :name1 AND y.key = x.key))
THEN x
ELSE y
END
FROM Property x
WHERE
x.setName = :name2
Меня также интересует выбор отдельных строк таким же образом, с помощью key
, который, я полагаю, будет выглядеть следующим образом (если бы только COALESCE работал для нескалярных значений):
SELECT
COALESCE(y, x)
FROM Property x, Property y
WHERE
x.key = :key AND
x.setName = :name1 AND
y.key = :key AND
y.setName = :name2