2017-12-18 80 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中添加表名本身。 –