Re[6]: Можно ли заменить UNION на какой-нибудь JOIN?
От: Donz Россия http://donz-ru.livejournal.com
Дата: 02.08.09 09:35
Оценка:
Здравствуйте, elmal, Вы писали:

E>
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?
От: elmal  
Дата: 02.08.09 10:20
Оценка:
Здравствуйте, 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?
От: Donz Россия http://donz-ru.livejournal.com
Дата: 02.08.09 19:53
Оценка:
Здравствуйте, 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?
От: elmal  
Дата: 03.08.09 05:19
Оценка:
Здравствуйте, Donz, Вы писали:

D>Ты такой же предлагаешь?

Уже 2 раза писал, на этот раз попробую на чем-нидь похожим на SQL .
select A.* from A, A as AB join B on AB.id=B.id, A as AC join C on AC.id=C.id where A.id=AB.id or C.id=AC.id.

Алиасы забыл уже где и как ставятся, не уверен можно ли так, просто идею говорю.
Re: Можно ли заменить UNION на какой-нибудь JOIN?
От: MasterZiv СССР  
Дата: 03.08.09 06:10
Оценка: 4 (1)
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-ы невозможно.
Это разные операции.
Posted via RSDN NNTP Server 2.1 beta
Re: Можно ли заменить UNION на какой-нибудь JOIN?
От: MasterZiv СССР  
Дата: 03.08.09 06:15
Оценка:
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


можно писать так


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

ежели надо.
Posted via RSDN NNTP Server 2.1 beta
Re[2]: Можно ли заменить UNION на какой-нибудь JOIN?
От: MasterZiv СССР  
Дата: 03.08.09 06:18
Оценка:
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)

СКОБКИ В WHERE Н_Е Н_А_Д_О !!

(пожалуйста )
Posted via RSDN NNTP Server 2.1 beta
Re[4]: Можно ли заменить UNION на какой-нибудь JOIN?
От: MasterZiv СССР  
Дата: 03.08.09 06:21
Оценка:
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?
От: Lloyd Россия  
Дата: 03.08.09 06:47
Оценка: +1
Здравствуйте, MasterZiv, Вы писали:

MZ>СКОБКИ В WHERE Н_Е Н_А_Д_О !!


MZ>(пожалуйста )


Почему? С ними гораздо читабельнее и не надо помнить о приоритете операторов.
Re[5]: Можно ли заменить UNION на какой-нибудь JOIN?
От: Lloyd Россия  
Дата: 03.08.09 06:53
Оценка:
Здравствуйте, 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)
Re: Можно ли заменить UNION на какой-нибудь JOIN?
От: . Великобритания  
Дата: 03.08.09 07:10
Оценка: +1
Donz wrote:

> Эти ограничения накладывает Hibernate Criteria API.

Если ограничения не позволяют что-то сделать, то используй HQL/createQuery, а если и HQL слабоват, то используй SQL/createSQLQuery и не мучайся. Hibernate предназначен не усложнять жизнь, а упрощать.
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[6]: Можно ли заменить UNION на какой-нибудь JOIN?
От: MasterZiv СССР  
Дата: 03.08.09 07:11
Оценка:
Lloyd пишет:

> SELECT A.*

> FROM B, C
> JOIN A ON (B.a = A.a) OR (C.a = A.a)
Это вообще бред какой-то. У вас нет условия JOIN-а B и C.
Posted via RSDN NNTP Server 2.1 beta
Re[4]: Можно ли заменить UNION на какой-нибудь JOIN?
От: MasterZiv СССР  
Дата: 03.08.09 07:12
Оценка: -1
Lloyd пишет:

> Почему?


Потому что задолбало.

С ними гораздо читабельнее и не надо помнить о приоритете
> операторов.

О приоритетах операций помнить всё равно надо.
А скобки МЕШАЮТ читать.
Posted via RSDN NNTP Server 2.1 beta
Re[7]: Можно ли заменить UNION на какой-нибудь JOIN?
От: Lloyd Россия  
Дата: 03.08.09 07:13
Оценка: +1
Здравствуйте, MasterZiv, Вы писали:

>> SELECT A.*

>> FROM B, C
>> JOIN A ON (B.a = A.a) OR (C.a = A.a)
MZ>Это вообще бред какой-то.

Где именно?

MZ>У вас нет условия JOIN-а B и C.


А B и C и не должны JOIN-иться по условию задачи.
Re[5]: Можно ли заменить UNION на какой-нибудь JOIN?
От: Lloyd Россия  
Дата: 03.08.09 07:15
Оценка:
Здравствуйте, MasterZiv, Вы писали:

>> Почему?


MZ>Потому что задолбало.


И что?

MZ>С ними гораздо читабельнее и не надо помнить о приоритете

>> операторов.

MZ>О приоритетах операций помнить всё равно надо.


В приведенном примере не надо.

MZ>А скобки МЕШАЮТ читать.


Если только тебе. Мне лично они только помогают.
Re[2]: Можно ли заменить UNION на какой-нибудь JOIN?
От: Donz Россия http://donz-ru.livejournal.com
Дата: 03.08.09 10:53
Оценка:
Здравствуйте, 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?
От: Donz Россия http://donz-ru.livejournal.com
Дата: 03.08.09 10:55
Оценка:
Здравствуйте, ., Вы писали:

>> Эти ограничения накладывает Hibernate Criteria API.

.>Если ограничения не позволяют что-то сделать, то используй HQL/createQuery, а если и HQL слабоват, то используй SQL/createSQLQuery и не мучайся. Hibernate предназначен не усложнять жизнь, а упрощать.

Нет, смысл в том, что у меня условия выборки будут динамически присоединяться к обсуждаемому запросу. То есть, из метода я наружу отдаю Criteria, на который можно будет наложить дополнительные ограничения.
Собственно, сила Criteria API именно в этом.
Re[2]: Можно ли заменить UNION на какой-нибудь JOIN?
От: Donz Россия http://donz-ru.livejournal.com
Дата: 03.08.09 10:57
Оценка:
Здравствуйте, 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?
От: MasterZiv СССР  
Дата: 03.08.09 11:10
Оценка:
Donz пишет:

> Нет, не будет, так как за пределы метода, составляющего критерий,

> отдается не результат запроса, а объект Criteria, к которому еще будут
> присоединятся условия выборки. Именно поэтому мне нужен один запрос не
> через юнион.

Ты занимаешься какой-то ерундой. Ну, отдавай не Criteria, а массив Criteria.
Или отдавай что-то другое. Какая разница-то ?

> 1)Это гипноз?

> 2)Да вроде почти получилось.

Это в частном конкретном случае получилось.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: Можно ли заменить UNION на какой-нибудь JOIN?
От: elmal  
Дата: 03.08.09 11:46
Оценка:
Здравствуйте, Donz, Вы писали:

D>Нет, смысл в том, что у меня условия выборки будут динамически присоединяться к обсуждаемому запросу. То есть, из метода я наружу отдаю Criteria, на который можно будет наложить дополнительные ограничения.

D>Собственно, сила Criteria API именно в этом.
Хм, у тебя задача похоже один в один как у меня была . Я например HQL динамически генерил, никакое CriteriA API не использовал. А наружу отдавал класс, на основании информации которого можно однозначно построить HQL запрос (там информация о критериях поиска, о сущностях, кто на что мапится + информация о зависимостях, ну и параметры и значения естественно). Получилось достаточно удачно, удалось выдержать впоследствии такие требования, как интеграция с внешними сервисами (то есть сначала ищем во внешних сервисах, зетем то, что они вернут, используем как параметры запроса).
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.