scala slick左联接多个表以顺序获取结果

时间:2018-07-26 17:15:09

标签: scala left-join slick

我使用的是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))

但是此代码导致

  

(描述,产品,价格,[期权[货币])

行重复

1 个答案:

答案 0 :(得分:0)

通过符合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,但这显然是不可扩展的。