E>select A.* from A, A join A.b B, A join A.c C where A.id=B.id or A.id=C.id
E>
E>Вот только не факт, что я его правильно написал, но один раз я точно что-то подобное проворачивал на хибернейте, помню точно, что я делал union и без left join, и без in, и основная идея была именно такая — пересечение таблицы с собой под разными алиасами (задача была другой помнится). Просьба попробовать, и сообщить, если получится — я тогда в следующий раз, когда это понадобится, поиском найду, а то опять забуду .
Сейчас под рукой даже парсера нет, но подозреваю, что ошибка в синтаксисе будет. Да и вообще не очень понял смысл запроса. У A нет информации о таблицах B и C. B, C могут связаться с A только по идентификатору из A и все. Откуда поля A.b, A.c?
Хитропопые маппинге с алиасами на саму себя уже есть, правда, для других целей.
Re[7]: Можно ли заменить UNION на какой-нибудь JOIN?
Здравствуйте, Donz, Вы писали:
D>Сейчас под рукой даже парсера нет, но подозреваю, что ошибка в синтаксисе будет. Да и вообще не очень понял смысл запроса. У A нет информации о таблицах B и C. B, C могут связаться с A только по идентификатору из A и все. Откуда поля A.b, A.c?
A.b это если на sql перевести A inner join B on A.id=B.id. Я просто привык уже к синтаксису HQL, потому так и написал, я считал что B замаплен на A как аттрибут. Смысл запросв следующий — у нас получается 3 таблицы, одна A, другая join A и B, третья join A и C. Делаем их пересечение с использованием or, соответственно union готова.
Re[8]: Можно ли заменить UNION на какой-нибудь JOIN?
Здравствуйте, elmal, Вы писали:
D>>Сейчас под рукой даже парсера нет, но подозреваю, что ошибка в синтаксисе будет. Да и вообще не очень понял смысл запроса. У A нет информации о таблицах B и C. B, C могут связаться с A только по идентификатору из A и все. Откуда поля A.b, A.c? E>A.b это если на sql перевести A inner join B on A.id=B.id. Я просто привык уже к синтаксису HQL, потому так и написал, я считал что B замаплен на A как аттрибут. Смысл запросв следующий — у нас получается 3 таблицы, одна A, другая join A и B, третья join A и C. Делаем их пересечение с использованием or, соответственно union готова.
Теперь понял. Lloyd предложил именно этот вариант, если не ошибаюсь:
SELECT A.*
FROM A
LEFT JOIN B ON B.a = A.a
LEFT JOIN C ON C.a = A.a
WHERE (B.a IS NOT NULL) OR (C.a IS NOT NULL)
Ты такой же предлагаешь?
Re[9]: Можно ли заменить UNION на какой-нибудь JOIN?
Donz пишет:
> То есть, простейшее решение выглядит так: > select A.* from A inner join B on B.a = A.a > union > select A.* from A inner join C on C.a = A.a > > Но мне надо, чтобы селект был только один,
Это и есть один селект. UNION -- это часть одного
оператора SELECT.
причем таблицы в запрос могут > добавляться только через join'ы. > Эти ограничения накладывает Hibernate Criteria API.
Я сначала составляю > Criteria, который является обвязкой запроса, потом отдаю его, и > запросивший этот Criteria может добавить еще условия по своему выбору.
Ты точно так же можешь через Hib просто сделать 2-3 последовательных
запроса в одной транзакции, будет ровно то же самое.
(проблема только с дубликатами будет, но её можно
самому решить).
Так что проблема надуманная. Короче,
1) тебе это не нужно
2) формально заменить как-то UNION-ы на JOIN-ы невозможно.
Это разные операции.
Donz пишет:
> L>>SELECT A.* > L>>FROM A > L>>LEFT JOIN B ON B.a = A.a > L>>LEFT JOIN C ON C.a = A.a > L>>WHERE (B.a IS NOT NULL) OR (C.a IS NOT NULL)
> Можно подробнее? Оптимизацию запросов в БД начал изучать заново с > полгода назад. Пока я в этом запросе ничего криминального не вижу.
Криминального в нём то, что нет в нём критерия выборки,
и он будет обрабатывать все записи из таблицы A. Если она большая,
то будет небыстро. Запрос же с UNION потенциально может сначала
работать через таблицы B и C, которые могут быть меньше, и за счёт
этого давать большую производительность (впрочем, её часть всё
равно сожрёт сортировка для выполнения UNION).
Posted via RSDN NNTP Server 2.1 beta
Re[3]: Можно ли заменить UNION на какой-нибудь JOIN?
Здравствуйте, MasterZiv, Вы писали:
MZ>Криминального в нём то, что нет в нём критерия выборки, MZ>и он будет обрабатывать все записи из таблицы A. Если она большая, MZ>то будет небыстро. Запрос же с UNION потенциально может сначала MZ>работать через таблицы B и C, которые могут быть меньше, и за счёт MZ>этого давать большую производительность
А если:
SELECT A.*
FROM B, C
JOIN A ON (B.a = A.a) OR (C.a = A.a)
Donz wrote:
> Эти ограничения накладывает Hibernate Criteria API.
Если ограничения не позволяют что-то сделать, то используй HQL/createQuery, а если и HQL слабоват, то используй SQL/createSQLQuery и не мучайся. Hibernate предназначен не усложнять жизнь, а упрощать.
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[6]: Можно ли заменить UNION на какой-нибудь JOIN?
Здравствуйте, MasterZiv, Вы писали:
>> То есть, простейшее решение выглядит так: >> select A.* from A inner join B on B.a = A.a >> union >> select A.* from A inner join C on C.a = A.a >> >> Но мне надо, чтобы селект был только один,
>>Я сначала составляю >> Criteria, который является обвязкой запроса, потом отдаю его, и >> запросивший этот Criteria может добавить еще условия по своему выбору.
MZ>Ты точно так же можешь через Hib просто сделать 2-3 последовательных MZ>запроса в одной транзакции, будет ровно то же самое. MZ>(проблема только с дубликатами будет, но её можно MZ>самому решить).
Нет, не будет, так как за пределы метода, составляющего критерий, отдается не результат запроса, а объект Criteria, к которому еще будут присоединятся условия выборки. Именно поэтому мне нужен один запрос не через юнион.
MZ>Так что проблема надуманная. Короче, MZ>1) тебе это не нужно MZ>2) формально заменить как-то UNION-ы на JOIN-ы невозможно. MZ>Это разные операции.
1)Это гипноз?
2)Да вроде почти получилось.
P.S. не надо так агрессивно, тут все хорошие
Re[2]: Можно ли заменить UNION на какой-нибудь JOIN?
Здравствуйте, ., Вы писали:
>> Эти ограничения накладывает Hibernate Criteria API. .>Если ограничения не позволяют что-то сделать, то используй HQL/createQuery, а если и HQL слабоват, то используй SQL/createSQLQuery и не мучайся. Hibernate предназначен не усложнять жизнь, а упрощать.
Нет, смысл в том, что у меня условия выборки будут динамически присоединяться к обсуждаемому запросу. То есть, из метода я наружу отдаю Criteria, на который можно будет наложить дополнительные ограничения.
Собственно, сила Criteria API именно в этом.
Re[2]: Можно ли заменить UNION на какой-нибудь JOIN?
Здравствуйте, MasterZiv, Вы писали:
MZ>А, это MZ>select A.* from A inner join B on B.a = A.a MZ>union MZ>select A.* from A inner join C on C.a = A.a MZ>можно писать так MZ>select A.* MZ>from A MZ>left join B on B.a = A.a MZ>left join C on C.a = A.a MZ>ну и MZ>where b.a is not null or c.a is not null MZ>ежели надо.
Угу, это как раз уже и предложили.
Re[3]: Можно ли заменить UNION на какой-нибудь JOIN?
Donz пишет:
> Нет, не будет, так как за пределы метода, составляющего критерий, > отдается не результат запроса, а объект Criteria, к которому еще будут > присоединятся условия выборки. Именно поэтому мне нужен один запрос не > через юнион.
Ты занимаешься какой-то ерундой. Ну, отдавай не Criteria, а массив Criteria.
Или отдавай что-то другое. Какая разница-то ?
> 1)Это гипноз? > 2)Да вроде почти получилось.
Это в частном конкретном случае получилось.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: Можно ли заменить UNION на какой-нибудь JOIN?
Здравствуйте, Donz, Вы писали:
D>Нет, смысл в том, что у меня условия выборки будут динамически присоединяться к обсуждаемому запросу. То есть, из метода я наружу отдаю Criteria, на который можно будет наложить дополнительные ограничения. D>Собственно, сила Criteria API именно в этом.
Хм, у тебя задача похоже один в один как у меня была . Я например HQL динамически генерил, никакое CriteriA API не использовал. А наружу отдавал класс, на основании информации которого можно однозначно построить HQL запрос (там информация о критериях поиска, о сущностях, кто на что мапится + информация о зависимостях, ну и параметры и значения естественно). Получилось достаточно удачно, удалось выдержать впоследствии такие требования, как интеграция с внешними сервисами (то есть сначала ищем во внешних сервисах, зетем то, что они вернут, используем как параметры запроса).