Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / LEFT JOIN - чудеса / 22 сообщений из 22, страница 1 из 1
27.06.2002, 17:37:48
    #32034175
ASCRUS
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
Есть такой небольшой вьювер

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
create view v_SalaryValue_Current as
select sv.Salary_id, svm.WorkDate, sv.SalaryValue, sv.TarifValue
from SalaryValue sv
  inner join
   -- получаем последние даты действия
 
   (select svw.Salary_id, svs.SaveDate, max(svw.WorkDate) as WorkDate
    from SalaryValue svw
      inner join
       -- получаем последние даты изменения
 
       (select Salary_id, max(SaveDate) as SaveDate
        from SalaryValue svx
        where SaveDate <= dbo.fn_CalcDate() and 
              IsDelete is null and
              not exists(select *
                         from SalaryValue
                         where Salary_id = svx.Salary_id and
                               WorkDate = svx.WorkDate and
                               not IsDelete is null)
        group by Salary_id) 
       as svs on svs.Salary_id = svw.Salary_id and 
                 svs.SaveDate = svw.SaveDate
    where svw.IsDelete is null
    group by svw.Salary_id, svs.SaveDate)
   as svm on svm.Salary_id = sv.Salary_id and 
             svm.SaveDate = sv.SaveDate and 
             svm.WorkDate = sv.WorkDate


Он возвращает текущие значения по группам Salary_id, изменения которых храняться во времени и по дате изменений (т.е. есть возможность изменения задним числом) в таблице SalaryValue. У меня 10 групп, и одна из них не имеет текущего значения, поэтому такой запрос:
Код: plaintext
1.
2.
select *
from v_SalaryValue_Current

вернет 9 записей. Все вроде как правильно. Далее хотим получить параметры групп вместе с текущими значениями:
Код: plaintext
1.
2.
3.
select s.*, c.WorkDate, c.SalaryValue, c.TarifValue
from Salary s
  left join v_SalaryValue_Current c on s.Salary_id = c.Salary_id


По идее должно вернуться 10 записей, из которых одна группа в полях WorkDate, SalaryValue, TarifValue будет содержать NULL. А вот и ничего подобного - в этих полях этой группы стоят последние значения, которые были до того, как было зафиксированно удаление значения группы в таблице SalaryValue. Меняю LEFT JOIN на INNER JOIN - возвращается только 9 групп, то есть вьювер отработал правильно. Возвращаю обратно - опять та же байда. Смотрю план - в нем вьювер полноценно отрабатывает и возвращает 10 записей, хотя при плане простого запроса к вьюверу возвращается 9 записей. Честно говоря я страшно удивляюсь, потому как запрос, использующий вьювер, элементарен. Вместо вьювера тогда создаю inline функцию, результат естественно тот же. Тогда ради интереса создаю функцию, возвращаюшую табличную переменную, в которую запихиваю этот вьювер. Сразу в запросе вместе с такой функцией все начинает нормально работать. Вопрос на засыпку - что это - глюк или ... (на этом мысли заканчиваются) :)

Как вы наверное уже поняли SQL у меня 2000 (Desktop Engine version)
...
Рейтинг: 0 / 0
27.06.2002, 21:03:43
    #32034200
RatTail
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
Попробуйте после каждой группировки добавить ORDER BY по полям группировки. Будет ли разница?
...
Рейтинг: 0 / 0
28.06.2002, 11:56:59
    #32034253
ASCRUS
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
Не получится - в вложенных запросах нельзя использовать ORDER BY :(
...
Рейтинг: 0 / 0
28.06.2002, 12:03:32
    #32034256
Glory
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
BOL

Subquery Rules
A subquery is subject to a number of restrictions:
....
- ORDER BY can only be specified if TOP is also specified
....
...
Рейтинг: 0 / 0
28.06.2002, 13:02:43
    #32034269
SergSuper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
Не понимаю причем здесь order by, но Вы уверены что select * from Salary s возвращает 10 записей?
Терзают меня смутные сомнения...
...
Рейтинг: 0 / 0
29.06.2002, 13:32:54
    #32034390
ASCRUS
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
SergSuper:

Угу - возвращает именно 10 записей, так как в таблице Salary их именно столько и есть. Я в этой истории одного не понимаю - если вьювер возвращает 9 записей и если он обьединяется с Salary INNER JOIN - то тоже возвращается 9 записей. То почему блин по LEFT JOIN возвращается 10 полноценных записей, когда одна запись должна в своих полях (которые из вьювера) содержать NULL, а не значения. Я конечно понимаю, что вьювер немножко диковат, много раз обращается к одной и той же таблице в подзапросах, но факт остается фактом - возвращает то он именно то, что надо. Доказательством является хотя бы то, что достаточно перегнать результаты выполнения вьвера в темповую таблицу и в злополучном запросе вместо вьювера подставив темп. таблицу получим на выходе 10 записей, из которых одна запись в нужных полях будет содержать NULL. Главное прикольно, что обнаружил это чисто случайно, когда ради интереса в клиенте убил задним числом один тариф, нового не поставил и решил посмотреть, что покажет список текущих тарифов, который и нужен то только для того, чтобы юзер видел просто значения тарифов на данный момент. В реальных расчетах все равно используются другие скрипты получения значения тарифов из за постановки, где тариф имеет право меняться несколько раз в течении расчетного периода.

Проблему то я решил конечно через UDF, но все равно она меня волнует, потому как в БД есть вьювера и inline-функции, по сравнению с которыми данный вьювер является маленьким и детским, возвращает мало записей, фактически ничего не делает. Не хотелось бы такую же ситуацию получить не в безобидной как здесь варианте покажи доброму юзеру последние действующие тарифы, а в критичном для проекта месте.
...
Рейтинг: 0 / 0
29.06.2002, 13:43:15
    #32034391
Glory
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
А если, ради интереса, разбить первоначальный view на несколько других - попроще ?
...
Рейтинг: 0 / 0
30.06.2002, 13:44:08
    #32034428
ASCRUS
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
Glory:
Попробую, тогда напишу, что получилось :)

Ради интереса разглядывал планы выполнения скриптов:
Код: plaintext
1.
2.
select *
from v_SalaryValue_Current

и
Код: plaintext
1.
2.
3.
select s.*, c.WorkDate, c.SalaryValue, c.TarifValue
from Salary s
  left join v_SalaryValue_Current c on s.Salary_id = c.Salary_id

Во втором идет ветка ветвления LEFT JOIN, далее в ней план абсолютно идентичен первому запросу. Только вот в первом запросе в середине плана с 10 записей срезается до 9, а во втором так 10 записей и остаются. Чудеса блин :)
...
Рейтинг: 0 / 0
03.07.2002, 17:18:26
    #32034973
RatTail
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
Вот ответ от Peter Kavanagh (MCT, MCSE, MCDBA):
-----------------------------------------------------------
Have you tried executing the last query, but replacing the view_name with it's actual definition, i.e. making it a single complex query. One thing you must bear in mind is that a view does not contain any data. When the query optimiser is presented with a query which references a view, what it actually does is to merge the various clauses of the query with the clauses defined in the view and then treats it as a complex query for optimisation and compilation.
Because of this the optimiser is looking at this as a single multi-join query (2 inner joins and one left join). In such cases the optimiser will determine the order in which the joins are performed unless the order is forced ("OPTION clause", "FORCE ORDER" in BOL). I suspect the inclusion of the left join is resulting in a different resultset because it is not performing all the joins from the view before left joining with the Salary table. An alternative would be to select * from the view INTO a temporary table then left join the Salary table to this temporary table.
---------------------------------------------------------
Что скажите, таварышы? Мне кажется, он прав.
...
Рейтинг: 0 / 0
03.07.2002, 17:35:57
    #32034978
Rom
Rom
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
А ларчик то просто открывался
...
Рейтинг: 0 / 0
03.07.2002, 22:24:26
    #32035033
ASCRUS
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
Народ - а перевести можно, а то я не очень с нормальным инглишем в ладах, странно - в BOL все понимаю, а здесь чего то запутался :)
...
Рейтинг: 0 / 0
03.07.2002, 22:57:21
    #32035035
Cat2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
Б... Почему такую фигню нам должен объяснять Peter Kavanagh (MCT, MCSE, MCDBA):
По моему, после ухода Ron Soukup все становиться все более и боле запущено.
...
Рейтинг: 0 / 0
04.07.2002, 00:59:11
    #32035043
RatTail
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
2Cat2
Просвети, кто такой есть (был) Ron Soukup.
...
Рейтинг: 0 / 0
04.07.2002, 11:00:12
    #32035101
RatTail
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
2Cat2
>Почему такую фигню нам должен объяснять Peter Kavanagh (MCT, MCSE, MCDBA)

Может потому, что он до сих пор не знает, почему пиво "Очаково" называется живительным? Надо будет спросить у него. Кстати, заметил ли форум, как я исправил своё поведение? Раньше бы, после разоблачения "чудес", всем бы досталось. Особенно макропроцессору Аскруса, генерирующему каку-ту мутату.
...
Рейтинг: 0 / 0
04.07.2002, 12:21:18
    #32035119
Glory
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
2RatTail

Да, конечноб заметил(и)
...
Рейтинг: 0 / 0
04.07.2002, 16:28:37
    #32035205
ASCRUS
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
RatTail:
Ну что же поделать, такова наша многогранная жизнь. Каждый иногда генерит "какую-то мутоту". Кто то сам, а кто то через макропроцессор. Кому как больше нравится :)
...
Рейтинг: 0 / 0
04.07.2002, 16:49:48
    #32035214
RatTail
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
ASCRUS! Дорогой!
Тебе, на самом деле, надо памятник поставить!
Это вполне серьёзно, без шуток. Я по сравнению с тобой - ламма недобитая.
...
Рейтинг: 0 / 0
04.07.2002, 20:56:29
    #32035251
Cat2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
Re. RatTail. А мне прошлое поведение нравилось.

Ron Soukup - ведущий разработчик до версии 6.5 включительно. Его куда-то задвинули. Но в версии 6.5 было хорошо видно отличие стиля программирования от прочих продуктов той же фирмы.

Его книга "Основы SQL Server 6.5 (Inside SQL Server 6.5)" , Microsoft Press - лучшее, что я когда либо читал про SQL.
...
Рейтинг: 0 / 0
05.07.2002, 23:19:07
    #32035387
RatTail
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
2Cat2
Спасибо за инфу! Будем знать.
На поведение моё провоцирует меня мой омерзительный ник. Трудно представить, что бы я говорил "гадости" под ником, скажем, Винни Пух. :):):):):)
...
Рейтинг: 0 / 0
06.07.2002, 22:34:01
    #32035422
Robert Djabarov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
I concur about Inside SQL Server 6.5 and Ron Soukup. As far as "a mess that started up after he left," SQL definitely skewed up in a different direction, from the good-old "sequel" we used to know between 4.2a and 6.5. The reason for this was primarily the fact that IBM lost their best developers of UDB and M$ acquired their new SQL team comprised of IBM developers of UDB. Those who played with UDB would notice some similarity in the optimizer behavior.

By the way, I have to appologize for this foreign language I am using. I just didn't have a chance to enable multi-language support on my laptop.
...
Рейтинг: 0 / 0
06.07.2002, 23:37:29
    #32035426
RatTail
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
Gratia, amigo!
...
Рейтинг: 0 / 0
07.07.2002, 12:15:30
    #32035436
Cat2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LEFT JOIN - чудеса
Re: RatTail
Какой хороший меня псевдоним - можно и помурлыкать, а можно и когти показать.
Re: Robert Djabarov
На мой взгляд, лучше по-аглицки, чем "латиницей". Я в "латинице" вообще смысла уловить не могу.
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / LEFT JOIN - чудеса / 22 сообщений из 22, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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