отношение has_many и количество в списке выбора и где условия (количество связанных элементов) - PullRequest
0 голосов
/ 12 июня 2019

У меня очень простая модель DBIx :: Class, с одним объектом Person . Соответствующие столбцы: id_person , id_manager , имя , фамилия . человек принадлежит менеджеру . человек может быть руководителем, а иметь много подчиненных.

__PACKAGE__->has_many(
  "subordinates",
  "DBIx::Result::Person",
  { "foreign.id_manager" => "self.id_person" },
);

__PACKAGE__->belongs_to(
  "manager",
  "DBIx::Result::Person",
  { "foreign.id_person" => "self.id_person" },  
);

Как мне: 1. Найдите всех пользователей и добавьте в мой набор результатов дополнительный столбец «количество подчиненных» , в котором будут перечислены все пользователи и номера их подчиненных, включая 0?

Является ли единственным решением сделать это, а затем проверить атрибут «подчиненные» на длину в постобработке?

my $rs = $schema->resultset('Person')->search(
  undef,
  {
    prefetch => 'subordinates'
  }
);

По сути, что-то вроде:

SELECT
  person.*,
  ( SELECT
      count(*)
    FROM
      person subordinate
    WHERE 
      subordinate.id_manager = person.id_person
  ) AS subordinate_count
FROM
  person
;
  1. Возвращает подсчет подчиненных для только тех менеджеров, чей подсчет подчиненных ** выше, чем 2 ?

    ВЫБРАТЬ * ИЗ ( ВЫБРАТЬ человек. , ( ВЫБРАТЬ кол-(* * одна тысяча тридцать шесть) ОТ подчиненный человек ГДЕ subordinate.id_manager = person.id_person ) AS subordinate_count ОТ человек ) ГДЕ subordinate_count> 2
    ;

Я пробовал что-то подобное, но как мне подсчитать?

my $rs = $schema->resultset('Person')->search(
  {
    select => ['me.id_person'],
    group_by => ['me_id_person'],
    having => \[ count('subordinates.id_person) > ?', 2]
    join => 'subordinates',
  }
  1. Вернуть подсчет подчиненных для всех менеджеров , в том числе с 0 , но только для подсчета подчиненных с именем "Мэри"? Я смог выполнить группу, но в этом списке не будет менеджеров с нулевыми подчиненными по имени "Мэри". как те фильтруются.

Это то, что я хотел бы в чистом SQL:

SELECT
  person.*,
  ( SELECT
      count(*)
    FROM
      person subordinate
    WHERE 
      subordinate.id_manager = person.id_person
      AND subordinate.name = 'Mary'
  ) AS subordinate_count
FROM
  person
;
...