Kann ich mit Slick 2 eine relationale Schnittmenge oder Differenz ermitteln?
-
22-12-2019 - |
Frage
Ich verwende Slick Version 2.0.0-M3.Wenn ich zwei habe Query
s stellt Beziehungen des gleichen Typs dar, ich sehe, dass es eine gibt union
Operator, um sie inklusiv zu trennen, aber ich sehe keinen vergleichbaren Operator, um ihren Schnittpunkt oder ihre Differenz zu ermitteln.Gibt es solche Operatoren in Slick nicht?
Ich denke, das Vorstehende erklärt, wonach ich suche, aber falls nicht, hier ein Beispiel.Ich habe die Lieferantentabelle:
case class Supplier(snum: String, sname: String, status: Int, city: String)
class Suppliers(tag: Tag) extends Table[Supplier](tag, "suppliers") {
def snum = column[String]("snum")
def sname = column[String]("sname")
def status = column[Int]("status")
def city = column[String]("city")
def * = (snum, sname, status, city) <> (Supplier.tupled, Supplier.unapply _)
}
val suppliers = TableQuery[Suppliers]
Wenn ich Informationen zu Lieferanten erhalten möchte, die sich entweder in einer bestimmten Stadt befinden oder einen bestimmten Status haben, sehe ich, wie ich sie verwenden kann Query.union
dafür:
scala> val thirtySuppliers = suppliers.filter(_.status === 30)
thirtySuppliers: scala.slick.lifted.Query[Suppliers,Suppliers#TableElementType] = scala.slick.lifted.WrappingQuery@166f63a
scala> val londonSuppliers = suppliers.filter(_.city === "London")
londonSuppliers: scala.slick.lifted.Query[Suppliers,Suppliers#TableElementType] = scala.slick.lifted.WrappingQuery@1bea855
scala> (thirtySuppliers union londonSuppliers).foreach(println)
Supplier(S1,Smith,20,London)
Supplier(S4,Clark,20,London)
Supplier(S3,Blake,30,Paris)
Supplier(S5,Adams,30,Athens)
Kein Problem.Aber was ist, wenn ich nur die Lieferanten möchte, die es gibt? beide in einer bestimmten Stadt Und einen bestimmten Status haben?Scheint, als ob ich in der Lage sein sollte, so etwas zu tun:
(thirtySuppliers intersect londonSuppliers).foreach(println)
Oder wenn ich die Lieferanten in einer bestimmten Stadt haben möchte außer diejenigen, die einen bestimmten Status haben.Kann ich so etwas nicht tun:
(thirtySuppliers except londonSuppliers).foreach(println)
SQL hat UNION
, INTERSECT
, Und EXCEPT
Operationen und Slick's Query
Klasse hat eine union
Methode, die eine SQL-Abfrage mithilfe von SQL erstellt UNION
, aber ich sehe es nicht Query
Methoden in Slick zum Ableiten von Schnittmengen oder Differenzen.Vermisse ich sie?
Lösung
Es gibt eine Pull-Anfrage, die dies implementiert.Es wird wahrscheinlich in 2.0 oder 2.1 gelangen. https://github.com/slick/slick/pull/242 Wir müssen noch einige Details herausfinden und ein wenig aufräumen.
Andere Tipps
Die Operationen sind weitgehend zusammensetzbar, da ein Schnittpunkt nur aus zwei Filtern bestehen kann.Zum Beispiel
val intersect = suppliers.filter(_.status === 30).filter(_.city === "London")
oder außer:
val except= suppliers.filter(_.city === "London").filterNot(_.status === 30)