Подтвердить что ты не робот

SELECT DISTINCT в Scala slick

Я использую Slick 1, и я должен иметь возможность применить фильтр в запросе для поиска всех объектов, которые соответствуют условию в связанной таблице.

В этом примере с использованием документации Slick показано, что я пытаюсь сделать (это надуманный пример, близкий к моей ситуации).

Здесь я хочу, чтобы все кофе были предоставлены поставщиками на западном побережье. Я хочу только кофе, меня интересует только переход на поставщиков для применения фильтра:

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

Это работает нормально, но будет дублировать Coffees, если в таблице "Поставщики" имеется более одного соответствия.

Очевидным обходным решением является обычный SQL для выполнения SELECT DISTINCT; однако, я не могу найти способ сделать это здесь.

Теоретически вы могли бы сделать:

query.list.distinct

После того, как результаты уже возвращены; однако я также реализовал поддержку PAGING, поэтому вы не захотите обрабатывать результаты, как только они уже возвращаются из базы данных. Вот поддержка пейджинга:

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

Итак, вкратце, мне нужен способ указать SELECT DISTINCT в моем запросе, который гаснет.

У кого-нибудь есть идеи?

4b9b3361

Ответ 1

Как работа вокруг, вы можете попробовать использовать groupBy:

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

Он должен иметь ту же семантику, что и в отдельности, но я не уверен в производительности.

Ответ 2

С помощью slick 3.1.0 вы можете использовать функции distinct и distinctOn (заметки о выпуске Slick 3.1.0). Например:

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)

Ответ 4

Для разных на несколько столбцов coffee.name и 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)