Фильтр Scala Slick с условиями над двумя левыми объединенными таблицами - PullRequest
0 голосов
/ 05 февраля 2019

Я пытаюсь воспроизвести этот запрос в Slick.

SELECT *
FROM A
JOIN LEFT B AS B1 ON B1.aId = A.id && B1.condition = 'b1'
JOIN LEFT B AS B2 ON B2.aId = A.id && B2.condition = 'b2'

- (no condition, the query in a plain way)

- WHERE B1.status = 'delete' OR B2.status = 'delete'

- WHERE ((B1.status = 'read' AND B2.status <> 'delete') OR (B1.status <> 'delete' AND B2.status = 'read')

- WHERE B1.status = 'write' AND B2.status = 'write'

- WHERE B1.status = 'full' AND B2.status = 'full'

- WHERE ((B1.status = 'full' AND B2.status = 'write') OR (B1.status = 'write' AND B2.status = 'full')

Я не уверен, возможно ли это

До сих пор у меня есть что-то вроде

val query = for { ((a, b1Opt), b2Opt) <- ATable.aQuery join
  BTable.BQuery on ((joinTable, bTable) => join._1.id === _.AId && bTable.condition === "b1") join
  BTable.BQuery on ((joinTable, bTable) => join._1.id === _.AId && bTable.condition === "b2")
} yield (a, b1Opt, b2Opt)

и я пытаюсь что-то вроде этого

val filterB = query {
  case (a, b1Opt, b2Opt) => {
    bStatus match {
      case "delete" => b1Opt.map(b1 => b1.status === "delete") || b1Opt.map(b2 => b2.status === "delete")
    }

  }
}

1 Ответ

0 голосов
/ 05 февраля 2019

Из того, что вы описали, два последовательных left join таблицы B в таблице id должны преобразовываться в нечто похожее на следующее:

val joinQuery = for {
  ((a, b1), b2) <- tableA joinLeft tableB on ( (x, y) =>
                            x.id === y.aId && y.condition === "b1" )
                          joinLeft tableB on ( (x, y) =>
                            x._1.id = y.aId && y.condition === "b2" )
} yield (a, b1, b2)

И условие whereиз B1.status = 'delete' and B2.status = 'delete' должно выглядеть так:

val filterB = joinQuery.filter{ case (_, b1, b2) =>
  b1.filter(_.status === "delete").isDefined && b2.filter(_.status === "delete").isDefined
}

Обратите внимание, что left join s, b1 и b2 заключены в Option, следовательно, использование isDefined дляand операция.

В качестве еще одного примечания, возможно, стоит подумать о том, чтобы отфильтровать таблицу B с B.condition = 'b?' до уменьшенных B1 и B2 перед выполнением left join с.

...