2017-12-18 78 views
0
加入

我試圖用鵝毛筆要達到什麼下面PostgreSQL的查詢做:集團由多到多用鵝毛筆

select books.*, array_agg(authors.name) from books 
join authors_books on(books.id = authors_books.book_id) 
join authors on(authors.id = authors_books.author_id) 
group by books.id 

現在我有這個在我的奎爾版本:

val books = quote(querySchema[Book]("books")) 
val authorsBooks = quote(querySchema[AuthorBook]("authors_books")) 
val authors = quote(querySchema[Author]("authors")) 

val q: db.Quoted[db.Query[(db.Query[Book], Seq[String])]] = quote{ 
     books 
      .join(authorsBooks).on(_.id == _.book_id) 
      .join(authors).on(_._2.author_id == _.id) 
      .groupBy(_._1._1.id) 
      .map { 
       case (bId, q) => { 
        (q.map(_._1._1), unquote(q.map(_._2.name).arrayAgg)) 
       } 
      } 
    } 

如何擺脫結果中的嵌套查詢(db.Query [Book])並獲取Book?

+0

您是否試過flatMap而不是地圖?我不確定這一點,但只是猜測 – sparkr

+0

我認爲是這樣,但我不記得結果是什麼,我正在與這個查詢打了很長時間,我會在今天晚些時候再次回來,讓你知道。 –

回答

1

我用SQL可能會有點生疏,但你確定你的查詢是有效的嗎?特別是我發現你懷疑你做select books.*group by books.id即你直接返回你沒有分組的字段。並試圖直接翻譯錯誤的查詢是什麼讓事情出錯

解決它的一種方法是做所有領域的group by。假設Book聲明爲:

case class Book(id: Int, name: String) 

你可以做

val qq: db.Quoted[db.Query[((Index, String), Seq[String])]] = quote { 
    books 
     .join(authorsBooks).on(_.id == _.book_id) 
     .join(authors).on(_._2.author_id == _.id) 
     .groupBy(r => (r._1._1.id, r._1._1.name)) 
     .map { 
     case (bId, q) => { 
      // (Book.tupled(bId), unquote(q.map(_._2.name).arrayAgg)) // doesn't work 
      (bId, unquote(q.map(_._2.name).arrayAgg)) 
     } 
     } 
    } 

    val res = db.run(qq).map(r => (Book.tupled(r._1), r._2)) 

遺憾的是,似乎你不能申請Book.tupledquote,因爲你的錯誤

單子成分可以」 t使用應用連接表示

但您可以輕鬆地在db.run之後撥打電話取回您的Book

另一種方法是按Book.id進行分組,然後再次加入Book表以獲取所有字段。如果Book內有很多字段,這可能實際上更乾淨更快速。Book

+0

是的,這是一個有效的PostgreSQL查詢,但我不確定它是否正確轉換爲Quill的AST。 Book表中有20個字段。我會再次嘗試加入Book並讓你知道。 –

+0

@DanielAlexandrov,OK,我錯了,這可能是一個有效的SQL查詢** _ if _ ** DB支持_optional_ Feature T301「功能依賴」,但它看起來像Quill不提供在DSL中表示此功能的方法所以您仍然必須使用非可選方法之一:按所有字段進行分組或添加聯接。 – SergGr

+0

您對來自Book的超過1個字段進行分組的建議非常有用,顯然可以在GROUP BY中添加表名本身。 –