【问题标题】:group_by or distinct with postgres/dbix-classgroup_by 或与 postgres/dbix-class 不同
【发布时间】:2014-03-29 03:25:29
【问题描述】:

我有一个这样的帖子表:

+-----+----------+------------+------------+
|  id | topic_id |    text    |  timestamp |
+-----+----------+------------+------------+
| 789 |     2    |     foobar | 1396026357 |
| 790 |     2    |     foobar | 1396026358 |
| 791 |     2    |     foobar | 1396026359 |
| 792 |     3    |     foobar | 1396026360 |
| 793 |     3    |     foobar | 1396026361 |
+-----+----------+------------+------------+

如何按主题 id 对结果进行“分组”,同时提取最新记录(按时间戳降序排序)?

我了解到我可能不想要“group_by”,而是想要“distinct on”。我的 postgres 查询如下所示:

select distinct on (topic_id) topic_id, id, text, timestamp 
from posts 
order by topic_id desc, timestamp desc;

这很好用。但是,我不知道这是否是我可以在 DBIx::Class 中执行的操作,而无需编写自定义 ResultSource::View。我尝试了各种 group_by 与选择和列的安排,并尝试了 distinct => 1。如果/当返回结果时,它实际上并没有保留唯一性。

有没有办法通过结果集搜索来编写我正在尝试的查询,或者是否有更好的方法通过不同类型的查询来获得相同的结果?

【问题讨论】:

  • 旁白:从不使用texttimestamp等基本类型名称作为标识符。
  • 感谢您的评论。有时某些事情是无法控制的,“从不”或“总是”做某事不是选择的问题。谢天谢地,我能够将 col 名称用双引号括起来。

标签: postgresql dbix-class


【解决方案1】:

查看 DBIC Cookbook grouping results 中的部分。

我相信你想要的是类似这样的东西:

my $rs = $base_posts_rs->search(undef, {
    columns  => [ {topic_id=>"topic_id"}, {text=>"text"}, {timestamp=>"timestamp"} ],
    group_by => ["topic_id"],
    order_by => [ {-desc=>"topic_id"}, {-desc=>"timestamp"} ],
})

编辑:绕过严格的 SQL 分组的一种快速而肮脏的方法是这样的:

my $rs = $base_posts_rs->search(undef, {
    columns  => [
        { topic_id  => \"MAX(topic_id)" },
        { text      => \"MAX(text)" },
        { timestamp => \"MAX(timestamp)" },
    ],
    group_by => ["topic_id"],
    order_by => [ {-desc=>"topic_id"}, {-desc=>"timestamp"} ],
})

当然,根据需要使用适当的聚合函数。

【讨论】:

  • 谢谢。我最初确实去了食谱,并且像上面那样做让我陷入“必须出现在 GROUP BY 子句中或在聚合函数中使用”错误,我读过这是 postgres 不支持未分组列选择的结果:“当存在 GROUP BY 时,SELECT 列表表达式引用未分组的列是无效的,除非在聚合函数中,因为对于未分组的列将返回多个可能的值。”我试图将其他列添加到 group 子句中,但这会导致非唯一性。
  • 您可以查看我对可能对您有用的方法的修订答案。
  • 我可以通过一些语法调整获得预期的结果,但我想知道这是否会导致分组结果具有来自分组项目的字段值作为不同的结果每个选定字段上的聚合函数。不过,它目前看起来适用于我的目的。非常感谢。
猜你喜欢
  • 2017-05-17
  • 1970-01-01
  • 2011-07-09
  • 1970-01-01
  • 2016-08-25
  • 1970-01-01
  • 2013-01-21
  • 2013-03-08
  • 2011-07-09
相关资源
最近更新 更多