【问题标题】:Aggregate multiple columns without groupBy in Slick 2.0在 Slick 2.0 中聚合多个没有 groupBy 的列
【发布时间】:2014-01-28 18:59:36
【问题描述】:

我想使用 Slick 执行聚合,执行如下 SQL:

SELECT MIN(a), MAX(a) FROM table_a;

其中table_a 有一个INTa

在 Slick 中给出表定义:

class A(tag: Tag) extends Table[Int](tag, "table_a") { 
  def a = column[Int]("a")
  def * = a 
}
val A = TableQuery[A]
val as = A.map(_.a)

看来我有两个选择:

  1. 这样写:Query(as.min, as.max)

  2. 这样写:

    as
      .groupBy(_ => 1)
      .map { case (_, as) => (as.map(identity).min, as.map(identity).max) }
    

但是,无论哪种情况,生成的 sql 都不好。 1、生成了两个独立的sub-selects,相当于写了两个独立的查询。 2、生成如下:

select min(x2."a"), max(x2."a") from "table_a" x2 group by 1

但是,这种语法对于 Postgres 是不正确的(它按第一列值分组,在这种情况下是无效的)。事实上,AFAIK 不可能在 Postgres 中按常量值分组,除非省略 group by 子句。

有没有办法让 Slick 在没有 GROUP BY 的情况下发出包含两个聚合的单个查询?

【问题讨论】:

    标签: sql scala slick


    【解决方案1】:

    语法错误是一个错误。我创建了一张票:https://github.com/slick/slick/issues/630 在这种情况下,子查询是 Slick 的 SQL 编译器当前生成非最佳代码的限制。我们正在努力改善这种情况。

    作为一种解决方法,这里有一种模式可以在后台换出生成的 SQL 并保留其他所有内容:https://gist.github.com/cvogt/8054159

    【讨论】:

    • 好的,谢谢。对于 Postgres,事实证明 as.groupBy(_ => true)... 产生 SELECT ... GROUP BY true,这是有效的,但我怀疑它是否适用于所有 DBMS。
    【解决方案2】:

    我在 SQL Server 中使用了以下技巧,它似乎在 Postgres 中有效:

    select min(x2."a"), max(x2."a")
    from "table_a" x2
    group by (case when x2.a = x2.a then 1 else 1 end);
    

    group by 表达式中变量的使用使编译器误以为可能有多个组。

    【讨论】:

      猜你喜欢
      • 2016-07-30
      • 2020-11-05
      • 1970-01-01
      • 1970-01-01
      • 2021-11-01
      • 2019-10-12
      • 2021-11-05
      • 2020-11-04
      • 1970-01-01
      相关资源
      最近更新 更多