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 = :name1instead of the row withsetName = :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)
加载中,请稍侯......
精彩评论