powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Задачка для любителей поломать голову.
25 сообщений из 25, страница 1 из 1
Задачка для любителей поломать голову.
    #35715721
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имеются две таблицы, нужно сделать несимметричный джойн.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
create table a1(gk integer, id1 integer, f1 char( 1 ))
create table a2(gk integer, id2 integer, f2 char( 1 ))
go
insert into a1 values( 1 ,  1 , 'a')
insert into a1 values( 1 ,  2 , 'b')
insert into a1 values( 2 ,  1 , 'c')
insert into a1 values( 3 ,  1 , 'd')
go
insert into a2 values( 1 ,  1 , 'A')
insert into a2 values( 1 ,  2 , 'B')
insert into a2 values( 1 ,  3 , 'C')
insert into a2 values( 2 ,  1 , 'D')
insert into a2 values( 2 ,  2 , 'E')
go

В итоге должен получиться резалтсет:
gkid1 f1 id2 f211'a'1'A'11'a'2'B'11'a'3'C'12'b'21'c'1'D'21'c'2'E'31'd'То есть все строки таблицы a2 должны соединиться только с одной строкой из таблицы a1 (у которой id1=1), естественно учитывая связь по ключу группы (gk).
Спрашивается, как это сделать в одни-единственный select?
Задачу можно с легкостью решить через объединение или временные таблицы, но это решение будем считать неспортивным :)

Решение нужно для ASE 12.5.

Модератор: Тема перенесена из форума "Sybase ASA, ASE, IQ".
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35715768
Q
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Q
Гость
это видимо, так:
Код: plaintext
1.
select a1.gk, a1.id1, a1.f1, a2.id2, a2.f2
from a1 left join a2 on (a1.id1= 1 ) and (a1.gk=a2.gk)
хотя я не уверен, что "учитывая связь" это "=" :)
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35715777
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Усложним условие :)
А если не использовать 'left join on'? Как это сделать через отношение *= внутри where?
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35715784
Q
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Q
Гость
Сведем вопрос к философским:
1. Как в реляционной модели выглядит множество " несколько отсутствий строк"?
2. Как выглядит условие запроса для его получения?
:)
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35716232
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlУсложним условие :)
А если не использовать 'left join on'? Как это сделать через отношение *= внутри where?А что можно испорльзовать? Альтернативный синтаксис?
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35716249
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl пишет:

Я вот не понял, тебе шашечки, или ехать надо ?
Чего хочешь-то ?
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35717928
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну а вы как думаете, чего я могу хотеть? Есть гигантский запрос, сделанный в стиле *= вместо join. В него надо добавить еще одну таблицу как я уже описал. А я не могу придумать как описать это несимметричное соединение на *= синтаксисе.
Можно конечно переправить его на join синтакс, но мне уже просто любопытно а можно ли это вообще сделать на *=?
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35717963
expla
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если использовать твои данные, то внешнее соединение должно работать, но в общем случае твоё условие "(у которой id1=1)" (как я понял, если id1=1, то a1 соединяем с a2, в противном случае выводим только a1) внешним соединением так просто не реализуется, потому как сначала выполняется соединение независимо от значения id1, а затем вычисляются предикаты.
Уточни, пзл., условие.
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35718009
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owlможно ли это вообще сделать на *=?Подзреваю, что напрасно "Тема перенесена из форума "Sybase ASA, ASE, IQ"."
Это что за *= такое?
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35718108
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl пишет:

> Ну а вы как думаете, чего я могу хотеть? Есть гигантский запрос,
> сделанный в стиле *= вместо join. В него надо добавить еще одну таблицу
> как я уже описал. А я не могу придумать как описать это несимметричное
> соединение на *= синтаксисе.

переписывай на JOIN-ы.

> Можно конечно переправить его на join синтакс, но мне уже просто
> любопытно а можно ли это вообще сделать на *=?

Лучше пол-дня просидеть, а потом за час долетесь.
Переписывай. Давай текст если что, помогу.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35718124
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если это было правильно,

Код: plaintext
1.
select a1.gk, a1.id1, a1.f1, a2.id2, a2.f2
from a1 left join a2 on (a1.id1= 1 ) and (a1.gk=a2.gk)

то оно в старом синтаксисе будет выглядить так:

Код: plaintext
1.
2.
3.
select a1.gk, a1.id1, a1.f1, a2.id2, a2.f2
from a1, a2
where a1.id1= 1  and a1.gk *= a2.gk

Но если бы условие было бы a2.xxx=1 , то когда проверялось бы условие,
ДО join-а, или ПОСЛЕ join-а, сказать было бы нельзя (сервер мог бы делать как угодно).
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35718128
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
explaЕсли использовать твои данные, то внешнее соединение должно работать, но в общем случае твоё условие "(у которой id1=1)" (как я понял, если id1=1, то a1 соединяем с a2, в противном случае выводим только a1) внешним соединением так просто не реализуется, потому как сначала выполняется соединение независимо от значения id1, а затем вычисляются предикаты.
Уточни, пзл., условие.

Нет. Ваше предположение неверно. О том, когда будет проверяться это условие, вообще ничего сказать нельзя . Оно может проверяться когда угодно. Т.е. и до, и после JOIN-а.
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35718132
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlНу а вы как думаете, чего я могу хотеть?

Ещё можно вставить в список вывода поля, вытащенные подзапросом, или несколько полей, вытащенных подзапросами. Там может быть CASE, там уже легче.
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35718242
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivЕсли это было правильно,
...
то оно в старом синтаксисе будет выглядить так:
Да, запрос предложеный Q (через join), действительно выдает именно то что нужно. А вот твой запрос не работает, он выкидывает все записи из a1 в которых id1<>1. А их надо показывать.

А впрочем, я уже сам придумал. Всего-то полтора дня убил :)
Код: plaintext
1.
2.
3.
select a1.gk, a1.id1, a1.f1, a2.id2, a2.f2
from a1, a2
where (a1.id1= 1  and a1.gk*=a2.gk) or (a1.id1<> 1  and a2.gk is null)
Вот это действительно будет аналогом запроса
Код: plaintext
1.
select a1.gk, a1.id1, a1.f1, a2.id2, a2.f2
from a1 left join a2 on (a1.id1= 1 ) and (a1.gk=a2.gk)
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35718600
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl пишет:

Мой запрос и не должен был работать.

> select a1.gk, a1.id1, a1.f1, a2.id2, a2.f2
> from a1, a2
> where (a1.id1=1 and a1.gk*=a2.gk) or (a1.id1<>1 and a2.gk is null)
>
> Вот это действительно будет аналогом запроса
не будет.

когда вычисляется условие a1.id1=1 ? До или после join-а ?

когда вычислятся a2.gk is null ? До или после join-а ?

На все эти вопросы ответить нельзя.

Так что тебе надо переписывать через JOIN-ы.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35718747
Q
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Q
Гость
еще один существенный аргумент за join -- план выполнения (...*=...) or (...) приведет к nested loops table seek X table seek
Это может иметь последствия для "запроса из 30 таблиц" :)
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35718785
expla
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZivНет. Ваше предположение неверно. О том, когда будет проверяться это условие, вообще ничего сказать нельзя . Оно может проверяться когда угодно. Т.е. и до, и после JOIN-а.

Я говорю не о физическом выполнении операции соединения, а о логике выполнения запроса. Логически сначала выполняется декартово произведение отношений, затем вычисляются предикаты и отбрасываются ненужные записи. Так что условие id1=1 приведёт только к тому, что из результирующей выборки будут просто удалены все записи, которые этому условию не удовлетворяют (а в контрольном примере они есть). Но с семантикой ключевого слова left JOIN я плохо знаком, возможно она отличается от =... (+) или *=.
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35718791
Сахават Юсифов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
explaMasterZivНет. Ваше предположение неверно. О том, когда будет проверяться это условие, вообще ничего сказать нельзя . Оно может проверяться когда угодно. Т.е. и до, и после JOIN-а.

Я говорю не о физическом выполнении операции соединения, а о логике выполнения запроса. Логически сначала выполняется декартово произведение отношений, затем вычисляются предикаты и отбрасываются ненужные записи. Так что условие id1=1 приведёт только к тому, что из результирующей выборки будут просто удалены все записи, которые этому условию не удовлетворяют (а в контрольном примере они есть). Но с семантикой ключевого слова left JOIN я плохо знаком, возможно она отличается от =... (+) или *=.
лефт эт он пристраивается слева и сует до конца все что имеется хоть и некуда :(
декарт не был садистом а коодд ууууууууууууууууууууууууууууууу
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35718792
Сахават Юсифов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сахават Юсифов,


да воще декарт тут не причем
все грниды
а главынй му**к кантор
тольок блин на мельких базарах и ценят за то что можно нае..ать с кантором
можно конечено и с декартом
но это уже групповуха
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35719198
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Q пишет:
> Автор: Q
> еще один существенный аргумент за join -- план выполнения (...*=...) or
> (...) приведет к nested loops table seek X table seek
Чем это ж тебе nested loop не угодил ? Самое то что надо.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35719199
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
expla пишет:

> Я говорю не о физическом выполнении операции соединения, а о логике
> выполнения запроса. Логически сначала выполняется декартово произведение

Нифига. Именно о логике выполнения и нельзя ничего сказать.

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35719202
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сахават Юсифов пишет:

> да воще декарт тут не причем

Это у вас чего, обострение ?
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35719223
Q
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Q
Гость
MasterZiv
Чем это ж тебе nested loop не угодил ? Самое то что надо.

Nested loops сам по себе меня устраивает, меня беспокоят его внутренности. Лучше бы там были index seek, bookmark lookup... :)
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35720883
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivМой запрос и не должен был работать.ээээ.... а зачем писать неработающий запрос???

MasterZiv> select a1.gk, a1.id1, a1.f1, a2.id2, a2.f2
> from a1, a2
> where (a1.id1=1 and a1.gk*=a2.gk) or (a1.id1<>1 and a2.gk is null)
>
> Вот это действительно будет аналогом запроса
не будет.Судя по результату - это действительно аналог. Так что можешь не спорить. Если не веришь - проверь. Я оба запроса прогонял на ASE12.5. У тебя есть доступ до такой базы? Что-то мне подсказывает что есть :)

MasterZivТак что тебе надо переписывать через JOIN-ы.С точки зрения скорости запроса - ой надо....
...
Рейтинг: 0 / 0
Задачка для любителей поломать голову.
    #35721087
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl пишет:

> ээээ.... а зачем писать неработающий запрос???

Чтобы рассказать, как можно было бы написатЬ, но сказать,
что не будет работать. И чтобы все видели, как нельзя писать.


> Судя по результату - это действительно аналог. Так что можешь не
> спорить. Если не веришь - проверь. Я оба запроса прогонял на ASE12.5. У
> тебя есть доступ до такой базы? Что-то мне подсказывает что есть :)
Даже если он работает, то это не значит, что он будет работать
всегда и везде.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
25 сообщений из 25, страница 1 из 1
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Задачка для любителей поломать голову.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]