1

假设我正在使用物化路径来存储管理链:

  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

4

2 回答 2

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中最后一个 id的节点management_chain将以/2(无尾随/)结尾,并且不会包含在结果中。

该表达式不会使用索引,因此这对于大型表可能不可行。

但是我不知道这将如何转化为 JS 的东西。

SQLFiddle 示例:http ://sqlfiddle.com/#!15/75948/2

于 2014-10-24T20:36:19.160 回答
0

递归查找

作为一个例子,看看这段代码:

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。这些是不同分支的起点。

高温高压

于 2014-10-24T19:56:26.647 回答