我有一个名为users_edges
的表来存储公司员工结构。
它包含以下列:
id integer Auto increment [nextval('users_edges_id_seq')]
from_user_id integer NULL
to_user_id integer
link integer
索引:
UNIQUE from_user_id, to_user_id, link
PRIMARY id
外键:
from_user_id users(id) CASCADE CASCADE
to_user_id users(id) CASCADE CASCADE
执行董事是图表的顶部,因此该记录的from_user_id
为NULL
。
其他记录描述了员工之间的关系。
还有分离不同链接类型所需的链接列。
目前只有两种类型,但其数量将来会增加。
第一个链接类型为by departments
,第二个链接类型为custom
(未记录的位置加上区域位置)。
目前我需要得到所有员工的所有父母和子女。
该链接是可选的,如果未通过,我们需要合并所有结果。
我使用PHP
与PDO
构建查询:
WITH RECURSIVE temp AS (
SELECT t1.from_user_id FROM users_edges t1
WHERE t1.to_user_id = :from_user_id
AND link = :link -- This is optional
UNION
SELECT t2.from_user_id FROM users_edges t2
INNER JOIN temp ON temp.from_user_id = t2.to_user_id
WHERE link = :link -- This is optional
)
SELECT * FROM temp
WHERE from_user_id IS NOT NULL
如果我分别为同一个用户执行两个查询(link = 1
和link = 2
)并合并不包括重复项的结果,我会得到正确的结果。
结果:
link = 1
的此查询:
User 1
User 2
使用link = 2
:
User 1
User 3
合并和排除重复后的正确结果将是:
User 1
User 2
User 3
如果我选择一个查询(例如where link IN (1, 2)
),我会得到预期的员工,但会有额外的人员:
User 1
User 2
User 3
User 4
User 5
User 6
但显然不是灵活的解决方案。
问题是:如何使用一个查询进行操作?
也许我们需要在temp
中传递额外的参数或使用条件表达式?
我不会包括儿童查询,因为它类似,如果我意识到如何为父母做这件事,我可以用类似的方式让孩子们接受。