Необходимо найти среднее значение по многоуровневому вложенному SQL-запросу в Oracle - PullRequest
1 голос
/ 22 ноября 2011

Это что-то вроде беспорядка, и, возможно, есть какой-то гораздо лучший способ сделать это, но нам просто нужна информация для некоторых отчетов, над которыми мы работаем.

Итак, у нас есть несколько проектов; у каждого проекта есть куча задач, и с каждой задачей связан идентификатор типа документа. Проект может принадлежать одной или нескольким рабочим группам.

Мы хотим проанализировать проекты, в которых есть хотя бы одно задание типа документа x, а затем посмотреть, сколько у него рабочих групп. Я могу сделать это с:

   select distinct T.PROJECTID,
      (select COUNT(*) from TPM_PROJECTWORKGROUPS where PROJECTID=T.PROJECTID) as NumWorkgroups
   from TPM_TASK T
   where T.DOCUMENTTYPEID=17

Теперь мы хотим увидеть среднее количество рабочих групп по этим проектам. Так что я могу сделать:

select AVG(NumWorkgroups) FROM (
   select distinct T.PROJECTID,
      (select COUNT(*) from TPM_PROJECTWORKGROUPS where PROJECTID=T.PROJECTID) as NumWorkgroups
   from TPM_TASK T
   where T.DOCUMENTTYPEID=17
)

Однако мы хотим выполнить один и тот же запрос ко всем типам документов (их около 200). Я не могу найти способ сделать это без копирования и вставки запроса 200 раз. Я пробовал:

select DOCUMENTTYPEID, 
    (select AVG(NumWorkgroups) FROM (
       select distinct T.PROJECTID,
          (select COUNT(*) from TPM_PROJECTWORKGROUPS where PROJECTID=T.PROJECTID) as NumWorkgroups
       from TPM_TASK T
       where T.DOCUMENTTYPEID=DT.DOCUMENTTYPEID
    ))
from TPM_DOCUMENTTYPE DT

Однако я получаю сообщение об ошибке:

ORA-00904: "TPM_DOCUMENTTYPE"."DOCUMENTTYPEID": invalid identifier

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

Обновление для Джастина:

Вот пример схемы:

create table Test_Projects (
  id   number primary key
)

create table Test_Tasks (
  id   number primary key,
  project number,
  doctype number
)

create table Test_Workgroups (
  id   number primary key,
  workgroup number,
  project number
)

С некоторыми примерами данных:

insert into Test_Projects VALUES (1) --Create projects 1 and 2
insert into Test_Projects VALUES (2)
insert into Test_Tasks VALUES (1, 1, 5) --Project 1 has two tasks, doc types 5 and 6
insert into Test_Tasks VALUES (2, 1, 6)
insert into Test_Tasks VALUES (3, 2, 6) --Project 2 has one task, doc type 6
insert into Test_Workgroups VALUES (1, 1, 1) --Project 1 belongs to workgroups 1 and 2
insert into Test_Workgroups VALUES (2, 2, 1)
insert into Test_Workgroups VALUES (3, 2, 2) --Project 2 belongs to workgroup 2

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

Например, документ типа 5 имеет только проект 1, в котором есть 2 рабочие группы, поэтому среднее значение составляет 2. Документ типа 6 имеет 2 проекта (1 и 2) - 1 имеет 2 рабочие группы и 2 имеет одну рабочую группу - таким образом, среднее значение составляет 1,5.

Нам нужно перечислить все типы документов и среднее количество рабочих групп в каждой.

Я ожидаю, что этот запрос вернет:

DOCTYPE     AverageWorkgroups
-------     -----------------
5           2
6           1.5

1 Ответ

1 голос
/ 22 ноября 2011

Спасибо за пример данных.Это делает это намного понятнее.

Я полагаю, что это делает то, что вы хотите (я включаю расчеты для количества проектов и количества рабочих групп в выводе, а также только потому, что это облегчило мое тестирование)1003 *

SQL> ed
Wrote file afiedt.buf

  1  select t.doctype,
  2         count(distinct p.id) numProjects,
  3         count(*) numWorkgroups,
  4         count(*)/ count( distinct p.id) avgNumWorkgroups
  5    from test_projects p,
  6         test_tasks    t,
  7         test_workgroups w
  8   where p.id = t.project
  9     and p.id = w.project
 10*  group by t.doctype
SQL> /

   DOCTYPE NUMPROJECTS NUMWORKGROUPS AVGNUMWORKGROUPS
---------- ----------- ------------- ----------------
         6           2             3              1.5
         5           1             2                2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...