【问题标题】:How to ORDER before GROUP with DBIx::Class如何使用 DBIx::Class 在 GROUP 之前排序
【发布时间】:2011-05-26 02:29:48
【问题描述】:

我有一个简单的临时表,如下所示:

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

我的问题:如何获得 Fred 和 Jack 的单人最近批准状态的集合?也就是说,我想得到这个结果集:

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

帮助?

【问题讨论】:

  • 我不知道 perl 或 dbix,但这样做的 SQL 方法是将您的 modified 字段设置为 MAX(modified) as 'Modified',这将返回每个用户的最高日期。
  • 我玩过这个,使用类似的东西:SELECT item, user, status, MAX(modified) as most_recent FROM item_approval WHERE id=4;但它不会返回每个用户的最高日期;它只返回日期最高的单行。
  • 您需要同时执行MAX(Modified)GROUP BY User。没有GROUPMAX 为您提供查询的最大值。 GROUP BY 为您提供 GROUP BY 中每个组的最大值(或其他聚合函数,如 SUMAVG 等)。
  • 我把它改成了 [SELECT item, user, status, MAX( modified ) as modified FROM item_approval me WHERE (me.item = 4 ) GROUP BY user] 但这有只给的奇怪效果最大修改,而不是最大修改的行。也就是说,它给了我第一行,但“修改”值错误(为该用户修改了最大值的行的修改值)。

标签: sql perl group-by sql-order-by dbix-class


【解决方案1】:

根据您的 cmets 中描述的行为,我猜您的数据库是 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

这是一个相当慢的选项,因为它会为每一行重新运行子选择,然后为每个项目/用户组合拒绝除一行之外的所有内容。 其他数据库获得相似结果的方式略有不同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-29
    • 2011-11-18
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-09
    相关资源
    最近更新 更多