Рекурсивный запрос для Postgres для одной таблицы - PullRequest
0 голосов
/ 08 апреля 2020

Я хочу создать один запрос RECURSIVE для одной таблицы в Postgres, который в основном основан на родительском и дочернем элементах.

Вот демонстрационная таблица сотрудник с данными

id     parentid   managerid   status
------------------------------------
3741    [null]      1709        7    
3742     3741       1709        12    
3749     3742       1709        12    
3900     3749       1709        4

1) Если Status = 12 , то результатом будут данные, которые имеют status = 12 и все родители этого конкретный узел.

Ожидаемый результат будет:

 id     parentid   managerid   status
--------------------------------------
 3741   [null]      1709        7    
 3742    3741       1709        12    
 3749    3742       1709        12    

Для этого я попробовал запрос, который приведен ниже, работает нормально и дает правильный результат, даже если я изменю значение статуса, чем его работает нормально.

WITH RECURSIVE nodes AS (
      SELECT s1.id, case when s1.parentid=s1.id then null else s1.parentid end parentid,s1.managerid, s1.status
        FROM employees s1 WHERE id IN 
        (SELECT employees.id  FROM employees WHERE 
              "employees"."status" = 12 AND "employees"."managerid" = 1709)
      UNION ALL
      SELECT s2.id, case when s2.parentid=s2.id then null else s2.parentid end parentid,s2.managerid, s2.status
        FROM employees s2 JOIN nodes ON s2.id = nodes.parentid
)
SELECT distinct nodes.id, nodes.parentid, nodes.managerid, nodes.status  
      FROM nodes ORDER BY nodes.id ASC NULLS FIRST;

2) Если Status! = 12 , то результатом будут только все родительские этого конкретного узла.

Ожидаемый результат будет:

 id     parentid   managerid   status
--------------------------------------
 3741   [null]      1709        7    

Я хочу, чтобы запрос статуса не был равен некоторому значению.

Ответы [ 3 ]

0 голосов
/ 09 апреля 2020

С этим рекурсивным CTE:

with recursive cte as (
  select * from tablename
  where status = 12
  union all
  select t.* 
  from tablename t inner join cte c
  on c.parentid = t.id
)
select distinct * from cte;

См. Демоверсию . Результаты:

| id   | parentid | managerid | status |
| ---- | -------- | --------- | ------ |
| 3741 |          | 1709      | 7      |
| 3742 | 3741     | 1709      | 12     |
| 3749 | 3742     | 1709      | 12     |
0 голосов
/ 10 апреля 2020
WITH RECURSIVE CTE AS
(
 SELECT *
 FROM tablename
 WHERE status = 12
 UNION
 SELECT t.*
 FROM tablename t
 INNER JOIN cte c ON c.Id = t.parentid
)
SELECT t.*
FROM tablename t
LEFT JOIN cte c on t.id=c.id
WHERE c.id IS NULL
ORDER BY id ASC NULLS FIRST;
0 голосов
/ 09 апреля 2020

Это очень простое решение, но я думаю, что оно должно работать для небольших наборов данных

  SELECT * FROM employee
  WHERE 
    status=12
    OR id IN (
      SELECT DISTINCT parentId FROM employee WHERE status=12
    )
`
...