2016-12-08 4 views
0

Im a newbie to Slick.Scala slick left join не работает

Я хотел бы получить список идентификаторов из таблицы Echo, которые НЕ существуют в таблице program_vw.

Я написал запрос SQL, который работает

SELECT f.`id` 
FROM `Full`.`programs_vw` f 
LEFT JOIN `FULL`.`Echo` e ON f.`id`=e.`id` 
WHERE e.`id` IS NULL 
ORDER BY f.`id`; 

Я ссылался на примеры в http://slick.lightbend.com/doc/3.0.0/queries.html и написал это, но он не работает

val query = for { 
     (t, f) <- echoQuery.filter(_.id.isEmpty) join programsVwQuery on(_.id === _.id) 
     } yield (f.id) 
db.run(query.to[List].result) 
+0

Не могли бы вы объяснить немного больше, почему это не работает? Какой результат? –

ответ

0

Прежде всего, что вы сделали это не LEFT JOIN (я говорю о версии Slick). Для его создания вам необходимо использовать метод joinLeft.

Однако эта прямая коррекция неверна - она ​​производит подзапрос, который является плохим.

for { 
     (_, p) <- echoQuery.filter(_.id.isEmpty) 
       .joinLeft(programsVwQuery).on(_.id === _.id) 
} yield (p.map(_.id)) 

Примечание стороны: Имейте в виду, что выше p является Option (это LEFT JOIN в конце концов).

Исправленная решение было бы что-то вроде этого:

for { 
     (e, p) <- echoQuery 
       .joinLeft(programsVwQuery).on(_.id === _.id) if e.id.isEmpty 
} yield (p.map(_.id)) 

на мой взгляд, это хороший знак - это на самом деле читает почти как SQL.

Полностью правильное решение

Над порождает своего рода присоединиться вы хотите без подзапросов, но если сравнить его до нужного запроса, он на самом деле не производит то, что вы стремитесь. Если Slick часто можно прочитать как SQL, чем если бы наш SQL, как это (нужная версия):

SELECT f.`id` 
FROM `Full`.`programs_vw` f 
LEFT JOIN `FULL`.`Echo` e ON f.`id`=e.`id` 
WHERE e.`id` IS NULL 
ORDER BY f.`id`; 

чем точное отображение в Slick версии будет выглядеть следующим образом:

val query = 
(for { 
      (p, e) <- programsVwQuery 
        .joinLeft(echoQuery).on(_.id === _.id) if e.map(_.id).isEmpty 
} yield (p.id))).sortBy(id => id) 

db.run(query.result) // this runs the query 

В основном вы идете точно как в SQL в этом случае. Он идеально подходит к вашему желаемому запросу. Если вы посмотрите на сгенерированный SQL, это именно то, что вы хотели в начале.

+0

Как выполнить запрос? –

+0

Оформить мой обновленный ответ –

+0

спасибо. Ваше решение работает. Только одно изменение, хотя .. Мне пришлось использовать if e.map (_. Id) .isEmpty для фильтрации. –

Смежные вопросы