Sélectionnez DISTINCT dans Scala slick

J'utilise Slick 1, et je dois pouvoir appliquer un filtre dans une requête pour rechercher toutes les entités qui correspondent à une condition dans une table connexe.

Cet exemple utilisant la documentation Slick montre ce que j'essaie de faire (c'est un exemple artificiel qui est proche de Ma situation).

Ici, je veux tous les cafés qui sont fournis par les fournisseurs de la côte ouest. Je ne veux que le café, Je ne suis intéressé que par la navigation vers les fournisseurs pour appliquer le filtre:

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

Cela fonctionne ok, mais il dupliquera les cafés s'il y a plus d'une correspondance dans la table des fournisseurs.

La solution de contournement évidente est dans SQL normal pour faire un SELECT DISTINCT; cependant, je ne peux pas trouver un moyen de le faire ici.

Vous pourriez en théorie faire un:

query.list.distinct

Après que les résultats sont déjà retournés; cependant, j'ai également implémenté le support de pagination, donc vous ne voudriez pas traiter les résultats une fois que le déjà revenu de la base de données. Voici le téléavertisseur:

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

Donc, en un mot, je besoin un moyen de spécifier SELECT DISTINCT dans ma requête qui sort.

Quelqu'un a des idées?

29
demandé sur noplay 2013-08-15 20:05:59

4 réponses

Comme un travail, vous pouvez essayer d'utiliser groupBy:

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

Il devrait avoir la même sémantique que distincte, mais je ne suis pas sûr de la performance.

20
répondu Martin Kolinek 2013-08-17 08:55:30

Avec slick 3.1.0, vous pouvez utiliser les fonctions distinct et distinctOn (notes de version Slick 3.1.0). Par exemple:

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)
14
répondu Valerii Rusakov 2015-11-29 16:21:20

Je ne pense pas que cela soit encore implémenté. Voir https://github.com/slick/slick/issues/96

5
répondu Eugene Ryzhikov 2013-08-15 18:34:46

Pour distinct sur plusieurs colonnes coffee.name et du café.prix:

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)
2
répondu binshi 2016-06-03 08:51:25