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 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)
精彩评论