2016-11-15 2 views
1

Ich habe 2 Tabellen: Main und Update mit Spalten Name, ID und Abteilung. Ich möchte zuerst die Haupttabelle lesen, und wenn der Abteilungsfeldwert leer ist, könnte ich es aus der Update-Tabelle lesen.Scala Slick - Wie man einen Spaltenwert aus verschiedenen Tabellen nimmt

Zum Beispiel aus der unten stehenden Tabelle, soll ich die Abteilung Wert für KING von Update-Tabelle erhalten.

Wie dies mit scala glitschig aus laufender Ebene SQL-Abfragen erreichen?

Haupt

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

aktualisieren

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

Hier ist die Ebene SQL-Abfrage

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

Ich habe folgenden Code so weit definiert ...

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

Sie möchten vielleicht definieren eine benutzerdefinierte Funktion 'coalesce' (https://www.postgresql.org/docs/9.2/static/functions-conditional.html) und verwenden' '' val query = für { m <- mainQuery u <- updateQuery wenn m.id === u.id Abteilung = coalesce (m.department, u.department) } Ausbeute (m.id, Abteilung) '' ' –

Antwort

0

Zu allererst Ihrem Beispiel:

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

scheint eine Kombination von Werten aus zwei Tabellen zu holen.

DB-Ebene Lösung

auf DB-Ebene vielleicht so etwas wie dies würde für Sie arbeiten:

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

die meiner Meinung nach sehr ist Ihre ursprüngliche, gewünschte Abfrage in der Nähe (obwohl um ehrlich zu sein, ich bin nicht ganz sicher, wie ifNull in alle Datenbanken übersetzt wird).

Anwendungsebene Lösung

Auf Anwendungsebene, unter der Annahme, dass Sie Einzelfall-Klasse haben:

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

(die btw Sie können Sie für Typ für beide Tabellendefinitionen ausgepackt, wie sie sind identisch) könnte es so aussehen:

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

Danke. Ich werde das versuchen und Sie wissen lassen. –

+0

Ich kann nicht sicher sagen, dass das funktioniert hat. Die mehrfache Verwendung von Karten war verwirrend. –

+0

Ich nehme an, Sie haben nur die zweite Version ausprobiert? Haben Sie die erste Option überprüft? Der eine angezeigt von: "Auf DB-Ebene könnte etwas wie das für Sie arbeiten" <- es hat keine mehrere Karten. Auch was sagen "Kann nicht ... sagen, das hat funktioniert"? Sie waren verwirrt von mehreren Karten (im zweiten Beispiel), aber es tut was Sie brauchen oder es funktioniert nicht (Kompilieren oder zurückgeben Ergebnisse, die Sie erreichen wollten)? Nur neugierig. EDIT: Abschnitte zu meiner Antwort hinzugefügt, um deutlich anzuzeigen, dass es zwei Lösungen gibt. –

Verwandte Themen