JPQL коалесцирует не скаляры? - PullRequest
1 голос
/ 21 июня 2011

У меня есть таблица, в которой хранятся параметры конфигурации приложения, например:

 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

1 Ответ

0 голосов
/ 22 июня 2011

Возможно, вы можете создать запрос со следующей структурой:

SELECT
  Property p,
  CASE WHEN setName=:name1 
       THEN 1
       ELSE 0
  as orderColumn
FROM Property x
WHERE x.setName = :name1 OR (x.setName =:name2 AND (NOT EXISTS (SELECT y FROM Property y WHERE y.setName = :name1 AND y.key = x.key)))
ORDER BY orderColumn

(только из моей головы, даже не пытаясь)

...