Как ЗАКАЗАТЬ перед GROUP с DBIx :: Class - PullRequest
0 голосов
/ 15 декабря 2010

У меня есть простая временная таблица, которая выглядит так:

Table: item_approval

item  user  status         modified
2     fred  approved       2010-12-01 00:00:00
3     fred  approved       2010-12-02 00:00:00
4     fred  disapproved    2010-12-03 00:00:00
7     jack  unapproved     2010-12-05 00:00:00
4     fred  approved       2010-12-06 00:00:00
4     jack  unapproved     2010-12-07 00:00:00
4     fred  disapproved    2010-12-04 00:00:00

Я использую DBIx :: Class. Мой результат "Предмет" определяется с помощью:

__PACKAGE__->has_many(
  "item_approvals",
  "Schema::Result::ItemApproval",
  { "foreign.item" => "self.id" },
  { cascade_copy => 0, cascade_delete => 0 },
);

Что означает, что я могу сделать:

my $item = $schema->resultset('Item')->find({id=>4});

Что хорошо. Тогда я могу сделать:

my @approvals = $item->item_approvals;

чтобы получить такой набор результатов:

item  user  status         modified
4     fred  disapproved    2010-12-03 00:00:00
4     fred  approved       2010-12-06 00:00:00
4     jack  unapproved     2010-12-07 00:00:00
4     fred  disapproved    2010-12-04 00:00:00

Мой вопрос: как мне получить набор самого последнего одобрения Фреда и Джека? То есть я хочу получить этот набор результатов:

item  user  status         modified
4     fred  approved       2010-12-06 00:00:00
4     jack  unapproved     2010-12-07 00:00:00

Я пробовал такие вещи:

my @approvals = $item->search({}, {
    group_by => 'user',
    order_by => {-desc => 'modified'}
});

но «ORDER BY» выполняется после «GROUP BY», поэтому вместо этого я получаю такие вещи:

item  user  status         modified
4     fred  disapproved    2010-12-03 00:00:00
4     jack  unapproved     2010-12-07 00:00:00

Помощь

1 Ответ

1 голос
/ 15 декабря 2010

По поведению, описанному в ваших комментариях, я предполагаю, что ваша база данных - MySQL. Я также предполагаю, что ваша таблица item_approval имеет первичный ключ, который я назову PK.

Один из вариантов - использовать вспомогательный выбор, чтобы выбрать строку с наибольшим (самым последним) значением modified:

select item, user, status, modified 
from item_approval me 
where PK = (select s.PK from item_approval s where me.item = s.item and me.user = s.user order by s.modified desc, s.PK desc limit 1) 
and me.item = 4

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

...