¿Puedo obtener una intersección o diferencia relacional usando Slick 2?
-
22-12-2019 - |
Pregunta
Estoy usando Slick versión 2.0.0-M3.si tengo dos Query
Al representar relaciones del mismo tipo, veo que hay una union
operador para separarlos inclusive, pero no veo un operador comparable para obtener su intersección ni su diferencia.¿Estos operadores no existen en Slick?
Creo que lo anterior explica lo que estoy buscando, pero si no, aquí tienes un ejemplo.Tengo la tabla de proveedores:
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]
Si quiero saber sobre proveedores que están en una ciudad en particular o tienen un estado en particular, veo cómo usar Query.union
para eso:
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)
Ningún problema.¿Pero qué pasa si sólo quiero los proveedores que son ambos en una ciudad en particular y ¿Tiene un estatus particular?Parece que debería poder hacer algo como:
(thirtySuppliers intersect londonSuppliers).foreach(println)
O si quiero los proveedores en una ciudad en particular excepto los que tienen un estatus particular.¿No puedo hacer algo como:
(thirtySuppliers except londonSuppliers).foreach(println)
SQL tiene UNION
, INTERSECT
, y EXCEPT
operaciones, y Slick Query
la clase tiene un union
método que construye una consulta SQL usando SQL UNION
, pero no estoy viendo Query
métodos en Slick para derivar intersecciones ni diferencias.¿Los extraño?
Solución
Hay una solicitud de extracción que implementa esto.Probablemente lo convertirá en 2.0 o 2.1. https://github.com/slick/slick/pull/242 todavía necesitamosCalcule algunos detalles y limpie un poco.
Otros consejos
Las operaciones son bastante componentes en que un intersecto puede ser dos filtros.Por ejemplo
val intersect = suppliers.filter(_.status === 30).filter(_.city === "London")
o excepto:
val except= suppliers.filter(_.city === "London").filterNot(_.status === 30)