【问题标题】:scala slick left join multiple tables fetch result as a sequencescala slick left join 多个表以序列形式获取结果
【发布时间】:2024-04-28 08:30:02
【问题描述】:

我使用的是 scala 版本 2.12.6 和 slick 版本 3.2.3

我想用

连接来自 postgres 数据库的多个表
  • 描述和产品之间的1:1关系
  • 1:0/1 关系 在产品和价格之间和
  • 价格和货币之间的 1:n 关系

想要的输出:

(描述、产品、价格、Seq[Option[currencies])

到目前为止我所拥有的:

 val query = (for {
      (((description, product), price), currencies) <- ((descriptions.filter(_.language === lang.locale.toLanguageTag()) join products on (_.productId === _.id))  joinLeft prices on (_._2.id === _.priceId)) joinLeft currencies on (_._2.map(_.id) === _.priceId)
    } yield (description, product, price, currencies))

但是这段代码导致

(描述、产品、价格、[选项[货币])

有重复的行

【问题讨论】:

    标签: scala left-join slick


    【解决方案1】:

    根据符合 SQL 的标准,您的联接/左联接查询正确地产生 (description, product, Option[price], Option[currencies])

    要生成 Seq[Option[currencies]] 而不是 Option[currencies],我不确定 Slick 是否可行。理论上,groupBy 应该这样做,例如:

    val groupQuery = joinQuery.
      groupBy{ case (dsc ,prd, prc, cur) => (dsc ,prd, prc) }.
      map{
        case ((dsc ,prd, prc), group) => (dsc ,prd, prc, group.map(_._2).someAggFunction)
      }
    

    不幸的是,Slick 不支持 groupBy 聚合,例如 PostgreSQL 的 array_agg 或 Spark 的 collect_list。即使您有机会在 PostgreSQL 数据库上使用 slick-pg,它的 arrayAgg 方法 doesn't work 如广告所示,最后我检查了。

    SO link 中显示的一种解决方法是在客户端使用 Scala 的 groupBy,但它显然不可扩展。

    【讨论】: