Esta es una consulta muy extraña y no estoy seguro de cómo proceder con ella. A continuación se muestra la tabla.
id descendentId attr_type attr_value 1 {4} type_a 2 {5} type_a 3 {6} type_a 4 {7,8} type_b 5 {9,10} type_b 6 {11,12} type_b 7 {} type_x TRUE 8 {} type_y "ABC" 9 {} type_x FALSE 10 {} type_y "PQR" 11 {} type_x FALSE 12 {} type_y "XYZ" La entrada para la consulta será 1,2,3 .. la salida debe ser "ABC" .
La lógica es: recorrer descendantId desde 1,2,3 hasta que se attr_type x . Si se alcanza attr_type x , que es 7, 9 y 11, compruebe cuál es true . Por ejemplo, 7 es verdadero, luego obtenga su hermano de tipo type_y (verifique la fila 4) que es 8 y devuelva su valor.
Todo esto es formato de cadena.
Este es realmente un modelo de datos complicado para una consulta de este tipo, pero mi forma de hacerlo es aplanar la jerarquía primero:
WITH RECURSIVE typex(id, use) AS ( SELECT id, attr_value::boolean FROM weird WHERE attr_type = 'type_x' UNION SELECT w.id, typex.use FROM weird w JOIN typex ON ARRAY[typex.id] <@ w.descendentid ), typey(id, value) AS ( SELECT id, attr_value FROM weird WHERE attr_type = 'type_y' UNION SELECT w.id, typey.value FROM weird w JOIN typey ON ARRAY[typey.id] <@ w.descendentid ) SELECT id, value FROM typex NATURAL JOIN typey WHERE use AND id = 1; ┌────┬───────┐ │ id │ value │ ├────┼───────┤ │ 1 │ ABC │ └────┴───────┘ (1 row)Esto se puede resolver con CTE recursivos :
with recursive params(id) as ( select e::int from unnest(string_to_array('1,2,3', ',')) e -- input parameter ), rcte as ( select '{}'::int[] parents, id, descendent_id, attr_type, attr_value from attrs join params using (id) union all select parents || rcte.id, attrs.id, attrs.descendent_id, attrs.attr_type, attrs.attr_value from rcte cross join unnest(descendent_id) d join attrs on attrs.id = d where d <> all (parents) -- stop at loops in hierarchy ) select y.attr_value from rcte x join rcte y using (parents) -- join siblings where x.attr_type = 'type_x' and x.attr_value = 'true' and y.attr_type = 'type_y'