2015-11-18 2 views
0

Я использую Java/Play 2.4/Ebean и мне нужно найти все записи в таблице А, не имеют соответствующую запись в таблице В.Ebean LEFT JOIN с условием на правой стороне

Это SQL Я хотел бы Ebean генерировать:

select a.* 
from a 
left join b 
on a.b_id = b.id 
where b.id is null; 

Я думал, что это может быть правильный код, но это не так:

A = Ebean.find(models.A.class).fetch("bs").where().isNull("bs.id").findList(); 

, запрашивая все б для таблицы а (т.е. «BS») Ebean добавляет левое внешнее соединение на b. К сожалению, where() вызывает другое (внутреннее) соединение с таблицей b. Что-то вроде этого:

select a.* 
from a 
left outer join b 
on a.b_id = b.id 
join b 
on a.b_id = b.id 
where b.id is null; 

Очевидно, что это не будет работать.

Как пользователь Ebean выполняет левое соединение с условием на правой стороне?

ответ

0

Я также использую Ebean, но во многих случаях я предпочитаю иметь хороший контроль над запросами. Поскольку у вас есть LEFT JOIN и какое-то условие, я буду считать ваше дело «не-тривиальными».

  1. Как об использовании SQLQuery?

    final String sql = "select a.* from a left join b on a.b_id = b.id where b.id is null"; 
    
    SqlQuery sqlQuery = Ebean.createSqlQuery(sql); 
    
    // execute the query returning a List of MapBean objects 
    List<SqlRow> list = sqlQuery.findList(); 
    

    Тогда вы можете работать с SqlRow объектов и извлекать данные, необходимо

  2. Или с помощью RawSql объект? Вы можете создать его с помощью RawSqlBuilder. Затем используйте что-то вроде: Ebean.find(models.A.class).setRawSql(...).findList();


Edit: Я не эксперт SQL, но она не должна быть чем-то вроде:

оригинал:

select a.* from a left join b on a.b_id = b.id where b.id is null

изменить на:

select a.* from a left join b on a.b_id = b.id and b.id is null

Так что у вас есть условие where внутри соединения. И затем повторите попытку RawSqlBuilder # parse()

+0

Спасибо, что я пытался # 2, но havent получил его для правильной работы. Есть два метода - с RaqlSqlBuilder.parse (sql) .create() Я получаю правильные результаты, но очень медленный - он делает один запрос на строку из первого запроса, пытаясь получить таблицу B для каждого A.ID индивидуально. с unparse() Я получаю ошибку: [PersistenceException: Query бросил SQLException: недопустимый индекс столбца. Я подойду к прямому sql, если придется, но это означает либо создание объектов индивидуально (SLOW), либо значительные изменения в моих представлениях, чтобы больше не использовать реальные объекты. В таком случае, зачем использовать ORM? – latj

+0

Фактически, теперь, когда я смотрю более внимательно, когда я использую parse(), это не find (models.A.class) .setRawSql (rsql) .findList(), который вызывает одно-запрос на идентификатор. .. это должно быть в представлении.Возможно, у моего rsql отсутствует то, что нужно для просмотра ... – latj

+0

Вы могли отслеживать потерю производительности? Я обновил свой ответ с другой мыслью о моем - в отношении оператора SQL – Anton

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