与Quill一起加入多对多组合

问题描述 投票:0回答:1

我试图用Quill实现以下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

现在我的Quill版本中有这个:

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?

postgresql scala quill.io
1个回答
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.tupled中应用quote,因为您收到错误

monad组合物不能使用应用连接表达

但是你可以在db.run打电话回来你的Book后轻松做到这一点。

另一个选择是只通过Book.id进行分组,然后再次加入Book表以获得所有字段。如果Book中有许多字段,这可能实际上更干净,更快

© www.soinside.com 2019 - 2024. All rights reserved.