example scala slick

scala slick example



SELECT DISTINCT en Scala slick (4)

Estoy usando Slick 1, y debo poder aplicar un filtro en una consulta para buscar todas las entidades que coinciden con una condición en una tabla relacionada.

Este ejemplo que utiliza la documentación de Slick muestra lo que estoy tratando de hacer (este es un ejemplo ideado que está cerca de mi situación).

Aquí, quiero todos los cafés que proveen los proveedores en la costa oeste. Solo quiero el café, solo me interesa navegar a los proveedores para aplicar el filtro:

val westCoast = Seq("CA", "OR", "WA") val implicitInnerJoin = for { c <- Coffees s <- Suppliers if c.supID === s.id && s.state inSet westCoast } yield c

Esto funciona bien, pero duplicará los cafés si hay más de una coincidencia en la tabla de Proveedores.

La solución obvia es en SQL normal para realizar una SELECT DISTINCT; Sin embargo, no puedo encontrar una manera de hacerlo aquí.

Podrías en teoría hacer un:

query.list.distinct

Después de que los resultados ya se devuelven; sin embargo, también he implementado el soporte de PAGING, por lo que no querría procesar los resultados una vez que vuelvan de la base de datos. Aquí está el soporte de paginación:

query.drop(offset).take(limit).list

Entonces, en pocas palabras, necesito una manera de especificar SELECT DISTINCT en mi consulta que se apague.

¿Alguien tiene alguna idea?


Como solución, puedes intentar usar groupBy:

query.groupBy(x=>x).map(_._1)

Debería tener la misma semántica que distinta, pero no estoy seguro sobre el rendimiento.


Con Slick 3.1.0 puede usar funciones distinct y distinctOn ( Notas de la versión de Slick 3.1.0 ). Por ejemplo:

val westCoast = Seq("CA", "OR", "WA") val implicitInnerJoin = for { c <- Coffees s <- Suppliers if c.supID === s.id && s.state inSet westCoast } yield c db.run(implicitInnerJoin.distinctOn(_.name).result)



Para distintas en múltiples columnas coffee.name y coffee.price:

val westCoast = Seq("CA", "OR", "WA") val implicitInnerJoin = for { c <- Coffees s <- Suppliers if c.supID === s.id && s.state inSet westCoast } yield c db.run(implicitInnerJoin.map(f => (f.name, f.price, f.state)).distinctOn(p => (p._1, p._2)).result)