The best way to select data in a default tree tree

I have an application that needs parameters based on some fields. If a specific field is not found, the application should receive a less specific parameter value:

+----+-------+-------+------+--------------------------------------+
|PAR | ColA  | ColB  | ColC | value                                |
+----+-------+-------+------+--------------------------------------+
|Par1| *     | *     | *    | (this is the default value)  99      |
+----+-------+-------+------+--------------------------------------+
|Par1| ValA1 | *     | *    | (in case no valid ColB+ColC) 100     |
+----+-------+-------+------+--------------------------------------+
|Par1| ValA1 | ValB1 | *    | (in case no valid ColC)      200     |
+----+-------+-------+------+--------------------------------------+
|Par1| ValA1 | ValB1 | ValC1| (in case everything is specified) 333|
+----+-------+-------+------+--------------------------------------+

So, the user asks:

ValA1, ValB1, ValC1 for "Par1" → will receive "333"

when the user asks:

ValA1, ValB1, ValX for "Par1" → will receive "200".

I can easily do this using a query set or UNION (first it searches for all cols than search ColC = '' and then ColB = '' and ColC = '*' etc.), but is there a better way?

Example:

select value from mytab where PAR='Par1' and ColA='ValA1' and ColB='ValB1' and ColC='ValC1' 
UNION
select value from mytab where PAR='Par1' and ColA='ValA1' and ColB='ValB1' and ColC='*' 
UNION
select value from mytab where PAR='Par1' and ColA='ValA1' and ColB='*' and ColC='*' 
UNION
select value from mytab where PAR='Par1' and ColA='*' and ColB='*' and ColC='*' 

then get the "value" with the most columns! = '*'

I am using Postgresql, but I am open to using another db if that helps.

LTREE ?

EDIT: ( ). "PAR" ( ) , ...

+4
1
select value 
from mytab 
where PAR='Par1' 
ORDER BY
   CASE WHEN ColA='ValA1' and ColB='ValB1' and ColC='ValC1' THEN 0 else 1 END ASC,
   CASE WHEN ColA='ValA1' and ColB='ValB1' THEN 0 else 1 END ASC,
   CASE WHEN ColA='ValA1' THEN 0 else 1 END ASC
LIMIT 1

.

UPDATE:

WHERE

AND (ColA='ValA1' or ColA='*')
AND (ColB='ValB1' or ColB='*')
AND (ColC='ValC1' or ColC='*')

AND (
   (ColA='ValA1' and ColB='ValB1' and ColC='ValC1')
   OR
   (ColA='ValA1' and ColB='ValB1' and ColC='*')
   OR
   (ColA='ValA1' and ColB='*' and ColC='*')
   OR
   (ColA='*' and ColB='*' and ColC='*')
)
+2

Source: https://habr.com/ru/post/1692026/


All Articles