【问题标题】:Constructor can not be instantiated Slick Scala构造函数无法实例化 Slick Scala
【发布时间】:2017-11-15 09:21:11
【问题描述】:

我试图使用 Slick 将查询从 SQL 转换为 Scala 代码,但我在过滤子句中遇到编译器错误:构造函数无法实例化为预期类型 .

我在 Slick 中的代码:

val subquery = (for {
      pit <- PassInTripTable.table
      t <- TripTable.table if pit.tripNoFk === t.tripNo
    } yield (pit, t))
        .map{ case (pit, t) => ( pit, Case.If(t.townFrom <= t.townTo).Then(t.townFrom ++ t.townTo).Else(t.townFrom ++ t.townTo) )}
          .groupBy(_._1.idPsgFk)
            .filter{ case ((pit, count), group) => ( group.map(_._2).countDistinct === 1)}
                .map(_._1)
    val query = PassengerTable.table.filter(_.idPsg in subquery).map(_.name)
    db.run(query.result)

SQL 本身的查询:

select name from passenger
        where id_psg in
        (
          select id_psg from trip t,pass_in_trip pit
          where t.trip_no=pit.trip_no
          group by id_psg
          having count(distinct case when town_from<=town_to then town_from+town_to else town_to+town_from end)=1
        )

如果有人帮我找出错误,我将不胜感激。

【问题讨论】:

    标签: sql scala case slick


    【解决方案1】:

    通过查看您的代码,您匹配的类型似乎不应该是“((pit,count),group)”。

    Slick 中的 groupBy 仅返回 Tuple2 的集合。

    http://slick.lightbend.com/doc/3.0.0/queries.html

    所以,过滤器可能看起来像...

    .filter{ case (pit, count) => ( count.map(_._2).countDistinct === 1)}
    

    【讨论】:

    • 感谢您的建议。但是有了这样的过滤器,我得到了这样的异常:SlickTreeException: Cannot convert node to SQL Comprehension
    • 哦,我并不是要给出一个语法正确的答案。我只是在您的案例表达中阐明了这一点,您正在寻找 Tuple2[Tuple2[A,B],C] 并且在网站中它正在寻找 Tuple2[A,B]
    【解决方案2】:

    问题是 Slick .groupBy 需要一个 .map 调用,然后调用聚合函数。您可以找到详细信息here
    所以,试试这个:

    .groupBy(_._1.idPsgFk)
      .map{ case (key, group) => (key, group.map(_._2).countDistinct)}
        .filter{ case (_, count) => count === 1}
          .map(_._1)
    

    附言 我还在您的代码中发现了“难闻的气味”。由于理解,您会得到对,但看起来标准连接在这里更合适(并且更有效),例如:

    PassInTripTable.table.join(TripTable.table).on(_.tripNoFk === _.tripNo)
      .map{ case (pit, t) => ...}
    

    你为什么要使用这样的条件:
    Case.If(t.townFrom &lt;= t.townTo).Then(t.townFrom ++ t.townTo).Else(t.townFrom ++ t.townTo)?它的分支是一样的,所以等于t.townFrom ++ t.townTo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-04
      • 2016-10-29
      相关资源
      最近更新 更多