33009


scala初心者です。こういったコミュニティサイトでの質問自体も初めてなので、不備がありましたらその旨も教えてください。

# ■困っていること

SQLでの別名による表結合をどのように表現してよいかわからないです。

## やりたいこと（SQLで表現した場合）

[code]

    SELECT
      A.DepartmentCd,
      A.DepartmentName,
      COUNT(*)
    FROM
      Department A,
      Employee B
    WHERE
      A.DepartmentCd = B.DepartmentCd (+)
      A.DepartmentCd = '1000'
    GROUP BY
      A.DepartmentCd
    
[/code]

## scalaで書きかけ

下記①②をどうつなげてよいものか悩んでいます。  
①

[code]

    Department.filter(_.Departmentcd === '1000')
    
[/code]

②

[code]

    Employee.map(_.id.count).first leftjoin Department on (Department.DepartmentCd === Employee.DepartmentCd)
    
[/code]

# ■環境

scala 2.11.8  
postgres 9.5.1  
slick ~~2.11~~ 3.1.1  
Play Framework


CC BY-SA 3.0
2017-02-28T10:44:56.233
32992
2017-03-01T10:14:33.083
2017-03-01T03:55:22.643
20866
20866
question
scala slick
ScalaSlickで別名にしたtableを結合したい


**回答**

元々のSQLの妥当性は判断しかねますが、下記のように書けば期待しているSQLが発行されるかと思います。

[code]

    def select(): Future[Seq[(String, String, Int)]] = db.run {
      department
        .filter(_.DepartmentCd === "1000")
        .flatMap { d =>
          employee
            .filter(_.DepartmentCd === d.DepartmentCd)
            .map(_ => (d.DepartmentCd, d.DepartmentName))
        }
        .groupBy { case (cd, name) => (cd, name) }
        .map { case ((cd, name), group) => (cd, name, group.length) }
        .result
    }
    
[/code]

実行されるSQL

[code]

    select
      x2."DepartmentCd", x2."DepartmentName", count(1)
    from
      "Department" x2,
      "Employee" x3
    where
      (x2."DepartmentCd" = '1000') and
      (x3."DepartmentCd" = x2."DepartmentCd")
    group by x2."DepartmentCd", x2."DepartmentName"
    
[/code]

* * *

**蛇足**

Implicit inner joinsの書き方は、公式のドキュメントを参考にすると、下記のようになります。

<http://slick.lightbend.com/doc/3.1.1/sql-to-slick.html#implicit-inner-joins>

[code]

    department
      .flatMap { d =>
        employee
          .filter(_.DepartmentCd === d.DepartmentCd)
          .map(_ => (d.DepartmentCd, d.DepartmentName))
      }
      .result
    
[/code]

[code]

    select
      x2."DepartmentCd", x2."DepartmentName"
    from
      "Department" x2,
      "Employee" x3
    where
      (x3."DepartmentCd" = x2."DepartmentCd")
    
[/code]

これに`where DepartmentCd = '1000'`と`group by`の条件をつけたものが回答のコードです。

また、`.groupBy { case (cd, name) => (cd, name)
}`は引数の変数をそのまま返しているだけなので、[`identity`](https://github.com/scala/scala/blob/v2.11.8/src/library/scala/Predef.scala#L134)を使用して下記のように書けます。

[code]

    department
      .filter(_.DepartmentCd === "1000")
      .flatMap { d =>
        employee
          .filter(_.DepartmentCd === d.DepartmentCd)
          .map(_ => (d.DepartmentCd, d.DepartmentName))
      }
      .groupBy(identity)
      .map { case ((cd, name), group) => (cd, name, group.length) }
      .result
    
[/code]


CC BY-SA 3.0
2017-03-01T07:53:57.260
33009
2017-03-01T10:14:33.083
2017-03-01T10:14:33.083
3068
3068
32992
answer