Scala slick - 如何从不同的表中获取列值
Scala slick - How to take a column value from different tables
我有 2 个 tables:Main 和 Update,包含列名称、ID 和部门。
我想先读取 Main table,如果 department 字段值为空,我想从 Update table 读取它。
例如,从下面的 table,我应该从更新 table 中获取 KING 的部门值。
如何使用没有 运行 普通 sql 查询的 scala slick 实现这一点?
主要
+-------+----+------------+
+ name | id | department +
+-------+----+------------+
| KING | 10 | |
| BLAKE | 30 | SALES |
+-------+----+------------+
更新
+-------+----+------------+
+ name | id | department +
+-------+----+------------+
| KING | 10 | SYSTEMS |
| BLAKE | 30 | SALES |
+-------+----+------------+
这是简单的 sql 查询
SELECT
m.`name`,
m.`id`,
if(m.`department`='', u.`department`) as `department`
FROM `Main` m
FROM `Update` u ON m.id=u.id
到目前为止我定义了以下代码...
case class Main(name: Option[String],
id: Option[int],
department: Option[String])
case class Update(name: Option[String],
id: Option[int],
department: Option[String])
lazy val mainQuery = TableQuery[MainTableDefinition]
lazy val updateQuery = TableQuery[UpdateTableDefinition]
class MainTableDefinition(tag: Tag) extends Table[Main](tag, "Main") {
def name = column[Option[String]]("name")
def id = column[Option[int]]("id")
def department = column[Option[String]]("department")
override def * =
(name, id, department)<> (Main.tupled, Main.unapply)
}
class UpdateTableDefinition(tag: Tag) extends Table[Update](tag, "Update") {
def name = column[Option[String]]("name")
def id = column[Option[int]]("id")
def department = column[Option[String]]("department")
override def * =
(name, id, department)<> (Update.tupled, Update.unapply)
}
val query = for {
m <- mainQuery
u <- updateQuery if m.id === u.id
} yield (m, u)
db.run(query.to[List].result)
首先你的例子:
SELECT
m.`name`,
m.`id`,
if(m.`department`='', u.`department`) as `department`
FROM `Main` m
FROM `Update` u ON m.id=u.id
似乎从两个 table 中获取值的组合。
DB级解决方案
在数据库级别上,这样的方法可能对您有用:
val query = for {
m <- mainQuery
u <- updateQuery if m.id === u.id
} yield {
(m.id, m.name, m.department.ifNull(u.department))
}
我认为这与您最初想要的查询非常接近(尽管老实说我不完全确定 ifNull
在所有数据库中是如何翻译的)。
应用级解决方案
在应用程序级别,假设您有单个案例 class:
case class NameDepartment(name: Option[String],
id: Option[int],
department: Option[String])
(顺便说一句,你可以为两个 table 定义输入 unpacked 类型,因为它们是相同的)它可能看起来像这样:
val fetchOperation = (for {
m <- mainQuery
u <- updateQuery if m.id === u.id
} yield (m, u)
).result.map { results =>
results.map { case (m, u) =>
NameDepartment(m.name, m.id, m.department.orElse(u.department))
}
}
我有 2 个 tables:Main 和 Update,包含列名称、ID 和部门。 我想先读取 Main table,如果 department 字段值为空,我想从 Update table 读取它。
例如,从下面的 table,我应该从更新 table 中获取 KING 的部门值。
如何使用没有 运行 普通 sql 查询的 scala slick 实现这一点?
主要
+-------+----+------------+
+ name | id | department +
+-------+----+------------+
| KING | 10 | |
| BLAKE | 30 | SALES |
+-------+----+------------+
更新
+-------+----+------------+
+ name | id | department +
+-------+----+------------+
| KING | 10 | SYSTEMS |
| BLAKE | 30 | SALES |
+-------+----+------------+
这是简单的 sql 查询
SELECT
m.`name`,
m.`id`,
if(m.`department`='', u.`department`) as `department`
FROM `Main` m
FROM `Update` u ON m.id=u.id
到目前为止我定义了以下代码...
case class Main(name: Option[String],
id: Option[int],
department: Option[String])
case class Update(name: Option[String],
id: Option[int],
department: Option[String])
lazy val mainQuery = TableQuery[MainTableDefinition]
lazy val updateQuery = TableQuery[UpdateTableDefinition]
class MainTableDefinition(tag: Tag) extends Table[Main](tag, "Main") {
def name = column[Option[String]]("name")
def id = column[Option[int]]("id")
def department = column[Option[String]]("department")
override def * =
(name, id, department)<> (Main.tupled, Main.unapply)
}
class UpdateTableDefinition(tag: Tag) extends Table[Update](tag, "Update") {
def name = column[Option[String]]("name")
def id = column[Option[int]]("id")
def department = column[Option[String]]("department")
override def * =
(name, id, department)<> (Update.tupled, Update.unapply)
}
val query = for {
m <- mainQuery
u <- updateQuery if m.id === u.id
} yield (m, u)
db.run(query.to[List].result)
首先你的例子:
SELECT
m.`name`,
m.`id`,
if(m.`department`='', u.`department`) as `department`
FROM `Main` m
FROM `Update` u ON m.id=u.id
似乎从两个 table 中获取值的组合。
DB级解决方案
在数据库级别上,这样的方法可能对您有用:
val query = for {
m <- mainQuery
u <- updateQuery if m.id === u.id
} yield {
(m.id, m.name, m.department.ifNull(u.department))
}
我认为这与您最初想要的查询非常接近(尽管老实说我不完全确定 ifNull
在所有数据库中是如何翻译的)。
应用级解决方案
在应用程序级别,假设您有单个案例 class:
case class NameDepartment(name: Option[String],
id: Option[int],
department: Option[String])
(顺便说一句,你可以为两个 table 定义输入 unpacked 类型,因为它们是相同的)它可能看起来像这样:
val fetchOperation = (for {
m <- mainQuery
u <- updateQuery if m.id === u.id
} yield (m, u)
).result.map { results =>
results.map { case (m, u) =>
NameDepartment(m.name, m.id, m.department.orElse(u.department))
}
}