这是一个非常奇怪的查询,我不知道如何继续它。 下面是表格。
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"
查询的输入为1,2,3
..输出应为"ABC"
。
逻辑是 - 从1,2,3
循环遍历descendantId,直到达到attr_type x
。如果达到attr_type x
,即7,9和11,则检查哪一个是true
。对于例如那么7
是真的
得到type_y
类型的兄弟(检查第4行)8
并返回它的值。
所有这些都是字符串格式。
答案 0 :(得分:1)
对于这样的查询来说,这确实是一个复杂的数据模型,但我的方法是先将层次结构弄平:
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)
答案 1 :(得分:0)
这可以通过recursive CTEs解决:
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'