LEFT JOIN в языке запросов Hibernate

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

выберите * из day_timetable_timeslots t LEFT JOIN 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.

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

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

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

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

выберите o.id, book.id из DayTimetableTimeslots o левое внешнее соединение o.bookings book, где 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 LEFT JOIN golfnine_date_time_entity d ON d.start_time = t.start_time AND t.customer_id = d.customer_id AND d.start_date = '2010-01-24 ' ГДЕ t.customer_id = 11

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


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

выберите t.start_time, d.id из day_timetable_timeslots t LEFT JOIN 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 LEFT JOIN golfnine_date_time_entity d ON d.start_time = t.start_time И t.customer_id = d.customer_id И d.start_date = '2010-01-24' ГДЕ t. идентификатор_клиента = 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 левое соединение 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.deleted = 0 левое соединение book.dateTime dt2 с dt2.startDate = '2010-01-19' и dt2.deleted = 0


person Phil    schedule 15.08.2010    source источник
comment
Можете ли вы показать SQL, сгенерированный вашим HQL, и некоторые примеры данных с полученным результатом и желаемым результатом?   -  person RMorrisey    schedule 15.08.2010
comment
спасибо, я добавил больше комментариев к моему вопросу.   -  person Phil    schedule 15.08.2010


Ответы (1)


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

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

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

person RMorrisey    schedule 15.08.2010