Как написать запрос PostgreSQL, чтобы получить среднее число дочерних строк в одной таблице? - PullRequest
0 голосов
/ 22 октября 2018

Я работаю над существующей таблицей в PostgreSQL, в которой есть дочерние и родительские строки в одной таблице.Я не эксперт по базам данных, поэтому мне сложно написать запрос, который возвращает среднее число дочерних строк и отображать его вместе с родительской строкой.

Я создал функцию, но выполнение запроса занимает больше времени, поэтому мне нужно написать запрос без использования функций.Каков наилучший способ написать этот запрос, чтобы он выполнялся быстрее?

Пожалуйста, см. Изображение ниже, чтобы понять мою таблицу

Query

Мой текущий запрос

SELECT task_id, tak_or_project_name, 
    case when c.parent_id = 0 Then getProjectScore(task_id, 'score1') ELSE score1   end as score1,
    case when c.parent_id = 0 Then  getProjectScore(task_id, 'score2') ELSE score2  end as score2,
    case when c.parent_id = 0 Then getProjectScore(task_id, 'score3')  ELSE score3  end as score3
FROM tbl_task c

Ответы [ 3 ]

0 голосов
/ 22 октября 2018

Вы, кажется, хотите:

Select t.task_id, t.task_or_project_name, 
       coalesce(c.score1, t.score1) as score1,
       coalesce(c.score2, t.score2) as score2,
       coalesce(c.score3, t.score3) as score3
       t.Parent_id
from tbl_task t left join
     (select c.Parent_id, 
             avg(c.Score1) as score1,
             avg(c.Score2) as score2, 
             avg(c.Score3) as score3 
      from tbl_task c 
      where c.parent_id <> 0
      group by c.Parent_Id
     ) c
     on t.task_id = c.Parent_Id;
0 голосов
/ 22 октября 2018

Вот еще один способ:

SELECT
    t1.task_id,
    t1.name,
    COALESCE(ROUND(AVG(t2.score1), 1), 0) AS score1,
    COALESCE(ROUND(AVG(t2.score2), 1), 0) AS score2,
    COALESCE(ROUND(AVG(t2.score3), 1), 0) AS score3,
    t1.parent_id
FROM tbl_task t1
LEFT JOIN tbl_task t2
    ON CASE WHEN t1.parent_id = 0 THEN t1.task_id = t2.parent_id ELSE t1.task_id = t2.task_id END
GROUP BY t1.task_id, t1.name, t1.parent_id
ORDER BY t1.task_id

Производит:

| task_id | name                 | score1 | score2 | score3 | parent_id |
| ------- | -------------------- | ------ | ------ | ------ | --------- |
| 1       | Project1             | 18.3   | 13.0   | 25.0   | 0         |
| 2       | task1                | 10.0   | 10.0   | 10.0   | 1         |
| 3       | task2                | 15.0   | 15.0   | 20.0   | 1         |
| 4       | task3                | 30.0   | 14.0   | 45.0   | 1         |
| 5       | Project2             | 16.0   | 23.0   | 54.0   | 0         |
| 6       | task1                | 14.0   | 25.0   | 64.0   | 5         |
| 7       | task2                | 18.0   | 21.0   | 44.0   | 5         |
| 8       | Project3             | 0      | 0      | 0      | 0         |
| 9       | task without project | 15.0   | 14.0   | 19.0   | -1        |

https://www.db -fiddle.com / f / ebmaThfxucoZx7sHx4ukA / 0

0 голосов
/ 22 октября 2018

просто сделай это, наверное тебе поможет

Select a.task_id, a.task_or_project_name, 
    case when a.Parent_id = 0 then isnull(PScore1, Score1) else Score1 end as Score1,
    case when a.Parent_id = 0 then isnull(PScore2, Score2) else Score2 end as Score2,
    case when a.Parent_id = 0 then isnull(PScore3, Score3) else Score3 end as Score3,
    a.Parent_id
    from tbl_task as a
    left join (
        select Parent_id, 
               sum(Score1)/count(score1) as PScore1, 
               sum(Score2)/count(score2) as PScore2, 
               sum(Score3)/count(score3) as PScore3 
        from tbl_task as inner 
        where Parent_Id !=0 
        group by Parent_Id
    ) as parent on a.task_id = parent.Parent_Id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...