让我们说我正在使用物化路径来存储管理链:
Table: User
id name management_chain
1 Senior VP {1}
2 Middle Manager {1,2}
3 Cubicle Slave {1,2,3}
4 Janitor {1,2,4}
如何根据返回所有直接报告的用户ID构建查询,例如,如果给中间经理,则应该返回Cubicle Slave和Janitor,鉴于高级副总裁,它应该返回中间管理器。换句话说,什么是获取management_chain
包含在倒数第二个位置查询的id的所有记录的好方法(假设最后一个项代表用户自己的id)
换句话说,我如何表示以下SQL:
SELECT *
FROM USER u
WHERE u.management_chain @> {stored_variable, u.id}
我现在的JS:
var collection = Users.forge()
.query('where', 'management_chain', '@>', [req.user.id, id]);
出了哪些错误
ReferenceError: id is not defined
答案 0 :(得分:1)
假设management_chain
是整数数组(int[]
),您可以执行以下操作(在纯SQL中)
select *
from (
select id,
name,
'/'||array_to_string(management_chain, '/') as path
from users
) t
where path like '%/2/%';
这样可行,因为array_to_string()
不会将分隔符附加到字符串的末尾。因此,如果路径包含序列/2/
,则意味着有更多节点"低于"那个。 2
中management_chain
的最后一个ID为/2
的节点将以/
结尾(不会跟踪{{1}}),并且不会包含在结果中。
表达式不会使用索引,因此对于大型表可能不可行。
但是,我不知道这会如何转化为JS的东西。
SQLFiddle示例:http://sqlfiddle.com/#!15/75948/2
答案 1 :(得分:0)
使用RECURSIVE查找
举个例子来看看这段代码:
CREATE VIEW
mvw_pre_import_cellpath_check
(
pkid_cell,
id_cell ,
id_parent,
has_child,
id_path ,
name_path,
string_path
) AS WITH RECURSIVE cell_paths
(
pkid_cell,
id_cell ,
id_parent,
id_path ,
name_path
) AS
(
SELECT
tbl_cell.pkid ,
tbl_cell.cell_id ,
tbl_cell.cell_parent_id ,
ARRAY[tbl_cell.cell_id] AS "array",
ARRAY[tbl_cell.cell_name] AS "array"
FROM
ufo.tbl_cell
WHERE
(((
tbl_cell.cell_parent_id IS NULL)
AND (
tbl_cell.reject_reason IS NULL))
AND (
tbl_cell.processed_dt IS NULL))
UNION ALL
SELECT
tbl_cell.pkid ,
tbl_cell.cell_id ,
tbl_cell.cell_parent_id ,
(cell_paths_1.id_path || tbl_cell.cell_id),
(cell_paths_1.name_path || tbl_cell.cell_name)
FROM
(cell_paths cell_paths_1
JOIN
ufo.tbl_cell
ON
((
tbl_cell.cell_parent_id = cell_paths_1.id_cell)))
WHERE
(((
NOT (
tbl_cell.cell_id = ANY (cell_paths_1.id_path)))
AND (
tbl_cell.reject_reason IS NULL))
AND (
tbl_cell.processed_dt IS NULL))
)
SELECT
cell_paths.pkid_cell,
cell_paths.id_cell ,
cell_paths.id_parent,
(
SELECT
COUNT(*) AS COUNT
FROM
ufo.tbl_cell x
WHERE
((
cell_paths.id_cell = x.cell_id)
AND (
EXISTS
(
SELECT
1
FROM
ufo.tbl_cell y
WHERE
(
x.cell_id = y.cell_parent_id))))) AS has_child,
cell_paths.id_path ,
cell_paths.name_path ,
array_to_string(cell_paths.name_path, ' -> '::text) AS string_path
FROM
cell_paths
ORDER BY
cell_paths.id_path;
在寻找递归CTE时,有更多的例子可以在SO上找到。 但与您的示例相反,顶级单元格(管理器)在我的示例中具有parent_id = NULL。这些是不同分支的起点。
HTH