2014-01-28 56 views
2

我想執行與油滑執行SQL如下所示的聚合:骨料的多個列中油滑2.0

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

其中table_a具有INTa

在油滑給出的表定義:

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中,生成了兩個單獨的子選擇,就像編寫兩個單獨的查詢一樣。在2中,產生以下情況:

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

然而,此語法不是Postgres的(它按第一列值,這是無效的在這種情況下)是正確的。實際上,AFAIK不可能通過Postgres中的常量值進行分組,除了通過忽略group by子句。

有沒有一種方法可以讓Slick發出一個單獨的查詢,並且兩個集合都沒有GROUP BY

回答

2

語法錯誤是一個錯誤。我創建了一張票:https://github.com/slick/slick/issues/630 子查詢是Slick的SQL編譯器當前在這種情況下生成非最優代碼的限制。我們正在努力改善這種情況。

作爲一種解決方法,這裏是引擎蓋下換出生成的SQL,離開一切不變的模式:https://gist.github.com/cvogt/8054159

+0

好的,謝謝。對於Postgres,事實證明'as.groupBy(_ => true)...'產生了'SELECT ... GROUP BY true',這是有效的,儘管我懷疑它適用於所有的DBMS。 – kong

0

我使用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表達技巧的使用變量的編譯器,以爲可以有多個組。