开发者

JPQL Coalesce non-scalars?

I have a table storing application configuration parameters like so:

 setName | key        | value
----------------------------------
 dev     | FooEnabled | true
 dev     | BarEnabled | true
 qa      | FooEnabled | false
 ...etc...

Each parameter, a key/value combination, belongs to a particular "configuration set." It's easy to select all properties in a particular set:

SELECT p Parameter p WHERE p.setName = :name

So if I wanted all the parameters in config set named "dev" I'd get back

 dev | FooEnabled | true
 dev | BarEnabled | true

Now I'd like to select the union of two sets:

SELECT p Parameter p WHERE p.setName = :name1 OR p.setName = :name2

...but eliminate rows with duplicate keys by giving properties in set with name1 higher precedence than properties in set with name2. If name1 was "qa" and name2 was "dev", then this would return

 dev | FooEnabled | true
 qa  | BarEnabled | false

To clarify, the query should SELECT:

  • Every property from set with name name2, except when...
  • There is a property with the same key in set with name name1, in which case...
  • Select the row with setName = :name1 instead of the row with setName = :name2

What JPQL query will do this efficiently? If COALESCE worked with non-scalar values, then I imagi开发者_JAVA技巧ne that something like this could work:

SELECT
    COALESCE(x, y)
    FROM Property x, Property y
    WHERE
        x.setName = :name1 AND
        y.setName = :name2 AND
        x.key = y.key

but COALESCE only accepts scalar values. Any ideas?


Other queries attempted/failed:

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

I'm also interested in selecting individual rows in the same manner, by key, which I suppose would look like the following (if only COALESCE worked for non-scalars):

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


Possibly you can create a query with basically following structure:

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

(Just from my mind without having it tried)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜