Aliasing
Sometimes you may need to combine queries with the same data type, but possibly with different records. Start by importing:
import scalaql._
// Docs classes
import scalaql.docs.Hogwarts._
Do distinguish those Query
inputs, you could use as
method to give Query
input an alias:
val left = select[Student].as("left")
// left: Query[From[as[Student, "left"]], Student] = FROM(Hogwarts::Student AS "left")
val right = select[Student].as("right")
// right: Query[From[as[Student, "right"]], Student] = FROM(Hogwarts::Student AS "right")
Then you could use them both in one Query
.
For instance, let's find students peers:
case class Peer(who: String, age: Int, peer: Option[String])
val peers =
left
.leftJoin(right)
.on(_.age == _.age)
.map { case (left, rightOpt) =>
Peer(
who = left.name,
age = left.age,
peer = rightOpt.map(_.name)
)
}
// peers: Query[From[as[Student, "left"]] with From[as[Student, "right"]], Peer] = FROM(Hogwarts::Student AS "left") LEFT JOIN FROM(Hogwarts::Student AS "right") -> MAP(MdocSession::App::Peer)
To provide an aliased input, use the same as
method on from
:
val input =
from(students).as("left") &
from(students).as("right")
// input: From[as[Student, "left"]] with From[as[Student, "right"]] = From[as[+Hogwarts::Student,="left"]] & From[as[+Hogwarts::Student,="right"]]
Then run the Query
:
peers
.show(truncate = false)
.run(input)
// +--------+---+--------+
// |who |age|peer |
// +--------+---+--------+
// |Harry |19 |Harry |
// |Ron |18 |Ron |
// |Ron |18 |Hermione|
// |Ron |18 |Draco |
// |Hermione|18 |Ron |
// |Hermione|18 |Hermione|
// |Hermione|18 |Draco |
// |Draco |18 |Ron |
// |Draco |18 |Hermione|
// |Draco |18 |Draco |
// |Cedric |17 |Cedric |
// +--------+---+--------+
//
NOTE
Scala 2.12 doesn't support literal types, so you should alias using traits:
trait left
trait right
val left = select[Student].as[left]
val right = select[Student].as[right]