2016-11-15 3 views
1

У меня есть 2 таблицы: Main и Update с именами столбцов, идентификатором и отделом. Сначала я хотел бы прочитать главную таблицу, и если значение поля отдела пусто, я хотел бы прочитать его из таблицы обновлений.Scala slick - Как взять значение столбца из разных таблиц

Например, из таблицы ниже я должен получить значение отдела для KING из таблицы обновлений.

Как достичь этого, используя scala slick без запуска простых запросов sql?

Главная

+-------+----+------------+ 
+ name | id | department +    
+-------+----+------------+ 
| KING | 10 |   | 
| BLAKE | 30 | SALES  | 
+-------+----+------------+ 

Update

+-------+----+------------+ 
+ 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) 
+1

Возможно, вы захотите определить (https://www.postgresql.org/docs/9.2/static/functions-conditional.html) и использовать его '' 'val query = для { m <- mainQuery u <- updateQuery если m.id === u.id department = coalesce (m.department, u.department) } yield (m.id, department) '' ' –

ответ

0

Прежде всего ваш пример:

SELECT 
m.`name`, 
m.`id`, 
if(m.`department`='', u.`department`) as `department` 
FROM `Main` m 
FROM `Update` u ON m.id=u.id 

кажется принести комбинацию значений из двух таблиц.

решение уровня DB

На уровне БД может быть что-то, как это будет работать для вас:

val query = for { 
    m <- mainQuery 
    u <- updateQuery if m.id === u.id 
} yield { 
    (m.id, m.name, m.department.ifNull(u.department)) 
} 

который я считаю очень близко оригинал, нужный запрос (хотя если честно я не совсем уверен, как ifNull переведен на все базы данных).

решение Прикладного уровня

На прикладном уровне, при условии, что у вас есть один класс случая:

case class NameDepartment(name: Option[String], 
        id: Option[int], 
        department: Option[String]) 

(который кстати вы можете вы для распакован типа как для определения таблиц, поскольку они идентичный), это может выглядеть так:

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)) 
    } 
    } 
+0

Спасибо. Я попробую это и дам вам знать. –

+0

Не уверен, что это сработало. Использование карт несколько раз сбивало с толку. –

+0

Я предполагаю, что вы попробовали вторую версию? Вы проверили первый вариант? Тот, на который указывает: «На уровне БД может быть что-то подобное для вас» <- у него нет кратных карт. И что говорят «Не могу ... сказать, что это сработало»? Вы были смущены несколькими картами (во втором примере), но он делает то, что вам нужно, или он не работает (компилируйте или возвратите результаты, которые вы хотели достичь)? Просто любопытно. EDIT: Добавлены разделы моего ответа, чтобы четко указать, что есть два решения. –

 Смежные вопросы

  • Нет связанных вопросов^_^