LEFT JOIN в Hibernate Query Language - PullRequest
       2

LEFT JOIN в Hibernate Query Language

6 голосов
/ 15 августа 2010

Я пытаюсь сделать левое соединение на Hibernate Query Language, в MySQL я могу сделать это следующим образом:

выберите * из дневных_таблиц_ временных интервалов t ВЛЕВО ПРИСОЕДИНЯЕТСЯ golfnine_date_time_entity d ON d.start_time = t.start_time

В моей таблице day_timetable_timeslots у меня есть много временных интервалов на весь день с 15-минутными приращениями. например. 00:00:00, 00:15:00, 00:30:00, ... до конца дня. Так что он показывает мне все временные интервалы с любым совпадающим golfnine_date_time_entity, но я не могу понять, как это сделать на языке запросов Hibernate.

Ну, я могу сделать левое соединение следующим HQL.

выберите o.id, book.id из DayTimetableTimeslots o левое внешнее соединение o.bookings, где o.id> 0

Я не знаю, почему я должен поместить o.id> 0, но это работает.

Однако я хочу выбрать только book.id, где в бронировании есть условие где. Я попробовал:

выберите o.id, book.id из DayTimetableTimeslots o левое внешнее соединение o.bookings, где o.id> 0 и book.dateTime.startDate> '2010-01-01'

Но это не работает правильно, оно показывает только некоторые из DayTimetableTimeslots, но не все из них, как это должно быть.

Я в основном хочу сделать этот запрос MySQL в HQL.

выберите t.id как start_time_sequence, t.start_time как all_start_time, d. * Из day_timetable_timeslots t СЛЕДУЮЩЕЕ СОЕДИНЕНИЕ 01-24' ГДЕ t.customer_id = 11

Спасибо, Филипп


В MySQL я могу сделать следующее, и он показывает мне все заказы против их времени начала. Все времена запуска хранятся в файле day_timetable_timeslots.

выберите t.start_time, d.id из day_timetable_timeslots t СЛЕДУЮЩЕЕ СОЕДИНЕНИЕ golfnine_date_time_entity d ON d.start_time = t.start_time

'00:00:00', NULL
'00:15:00', NULL
'00:30:00', NULL
'00:45:00', NULL
'01:00:00', '443'
'01:15:00', NULL
'01:30:00', NULL
'01:45:00', NULL
'02:00:00', '444'

... на весь день он сравнивает идентификаторы golfnine_date_time_entity со временем в day_timetable_timeslots.

В этом запросе mysql хорошо то, что я могу установить некоторые критерии при бронировании, например.

выберите t.id, t.start_time, d.id из day_timetable_timeslots t СЛЕДУЮЩЕЕ СОЕДИНЕНИЕ ГДЕ t.customer_id = 11

Я получаю

... lots of data then
'31', '07:15:00', NULL
'32', '07:30:00', NULL
'33', '07:45:00', NULL
'34', '08:00:00', '501'
'35', '08:15:00', NULL
'36', '08:30:00', NULL
'37', '08:45:00', NULL
'38', '09:00:00', NULL
'39', '09:15:00', NULL
... lots more data

Таким образом, отображается только бронирование на указанную дату и идентификатор клиента.

Это так сложно сделать на HQL ...


Это соединение, которое я хочу в HQL.

выберите o.id, b.id из DayTimetableTimeslots o, LegacyDateTimeEntity b, где b.customer.id = 11 и b.startDate = '2010-02-07' и o.startTime = b.startTime

Дает этот SQL.

select
    daytimetab0_.id as col_0_0_,
    legacydate1_.id as col_1_0_ 
from
    day_timetable_timeslots daytimetab0_,
    golfnine_date_time_entity legacydate1_ 
where
    legacydate1_.customer_id=11 
    and legacydate1_.start_date='2010-02-07' 
    and daytimetab0_.start_time=legacydate1_.start_time

Но - он возвращает только 1 строку, потому что соответствует только один golfnine_date_time_entity, я хочу, чтобы все строки day_timetable_timeslots были возвращены.

Итак, я попробовал в HQL.

выберите o.id, o.bookings.size из DayTimetableTimeslots o левое соединение o.bookings левое соединение book.dateTime dt с dt.customer.id = 11 и dt.startDate = '2010-02-29', где 1 = 1

К сожалению, похоже, что игнорируется выражение with.

Возвращает этот SQL.

select
    daytimetab0_.id as col_0_0_,
    (select
        count(bookings3_.timeslot_id) 
    from
        golfnine_booking bookings3_ 
    where
        daytimetab0_.id=bookings3_.timeslot_id) as col_1_0_ 
from
    day_timetable_timeslots daytimetab0_ 
left outer join
    golfnine_booking bookings1_ 
        on daytimetab0_.id=bookings1_.timeslot_id 
left outer join
    golfnine_date_time_entity legacydate2_ 
        on bookings1_.date_time_id=legacydate2_.id 
        and (
            legacydate2_.customer_id=11 
            and legacydate2_.start_date='2010-02-29'
        ) 
where
    1=1

Который просто объединяет все соответствующие отношения между таблицами и игнорирует legacydate2_.customer_id = 11 и legacydate2_.start_date = '2010-02-29'


Я обнаружил, что это похоже на работу. Обратите внимание, что я ссылаюсь на dt2, который находится в предложении with.

выберите отличные o.startTime, dt2.id, book.uniqueDateTimeResource из DayTimetableTimeslots o левое соединение o.bookings book с book.deleted = 0 левое соединение book.dateTime dt2 с dt2.startDate = '2010-01-19' и dt2.deleted = 0

1 Ответ

1 голос
/ 15 августа 2010

Я могу вспомнить две потенциальные проблемы, с которыми вы сталкиваетесь:

  1. У вас есть проблемы с точностью даты / времени между вашим Java-кодом и кодом SQL.Вы можете попытаться скорректировать дату с небольшим шагом и посмотреть, отображаются ли правильные значения.

  2. Ваше отображение спящего режима неверно.Похоже, вы всегда присоединяетесь к нескольким столбцам?Ваша схема немного смущает меня.Используете ли вы аннотацию @JoinColumns для указания нескольких столбцов в вашей ассоциации (если вы используете аннотации) или эквивалент в файле отображения XML?

...