powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / LEFT JOIN - чудеса
22 сообщений из 22, страница 1 из 1
LEFT JOIN - чудеса
    #32034175
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть такой небольшой вьювер

Код: 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
LEFT JOIN - чудеса
    #32034200
Фотография RatTail
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуйте после каждой группировки добавить ORDER BY по полям группировки. Будет ли разница?
...
Рейтинг: 0 / 0
LEFT JOIN - чудеса
    #32034253
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не получится - в вложенных запросах нельзя использовать ORDER BY :(
...
Рейтинг: 0 / 0
LEFT JOIN - чудеса
    #32034256
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
LEFT JOIN - чудеса
    #32034269
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не понимаю причем здесь order by, но Вы уверены что select * from Salary s возвращает 10 записей?
Терзают меня смутные сомнения...
...
Рейтинг: 0 / 0
LEFT JOIN - чудеса
    #32034390
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SergSuper:

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

Проблему то я решил конечно через UDF, но все равно она меня волнует, потому как в БД есть вьювера и inline-функции, по сравнению с которыми данный вьювер является маленьким и детским, возвращает мало записей, фактически ничего не делает. Не хотелось бы такую же ситуацию получить не в безобидной как здесь варианте покажи доброму юзеру последние действующие тарифы, а в критичном для проекта месте.
...
Рейтинг: 0 / 0
LEFT JOIN - чудеса
    #32034391
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А если, ради интереса, разбить первоначальный view на несколько других - попроще ?
...
Рейтинг: 0 / 0
LEFT JOIN - чудеса
    #32034428
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
LEFT JOIN - чудеса
    #32034973
Фотография RatTail
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот ответ от 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
LEFT JOIN - чудеса
    #32034978
Rom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А ларчик то просто открывался
...
Рейтинг: 0 / 0
LEFT JOIN - чудеса
    #32035033
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Народ - а перевести можно, а то я не очень с нормальным инглишем в ладах, странно - в BOL все понимаю, а здесь чего то запутался :)
...
Рейтинг: 0 / 0
LEFT JOIN - чудеса
    #32035035
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Б... Почему такую фигню нам должен объяснять Peter Kavanagh (MCT, MCSE, MCDBA):
По моему, после ухода Ron Soukup все становиться все более и боле запущено.
...
Рейтинг: 0 / 0
LEFT JOIN - чудеса
    #32035043
Фотография RatTail
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2Cat2
Просвети, кто такой есть (был) Ron Soukup.
...
Рейтинг: 0 / 0
LEFT JOIN - чудеса
    #32035101
Фотография RatTail
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2Cat2
>Почему такую фигню нам должен объяснять Peter Kavanagh (MCT, MCSE, MCDBA)

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

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

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

Его книга "Основы SQL Server 6.5 (Inside SQL Server 6.5)" , Microsoft Press - лучшее, что я когда либо читал про SQL.
...
Рейтинг: 0 / 0
LEFT JOIN - чудеса
    #32035387
Фотография RatTail
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2Cat2
Спасибо за инфу! Будем знать.
На поведение моё провоцирует меня мой омерзительный ник. Трудно представить, что бы я говорил "гадости" под ником, скажем, Винни Пух. :):):):):)
...
Рейтинг: 0 / 0
LEFT JOIN - чудеса
    #32035422
Robert Djabarov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
LEFT JOIN - чудеса
    #32035426
Фотография RatTail
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Gratia, amigo!
...
Рейтинг: 0 / 0
LEFT JOIN - чудеса
    #32035436
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Re: RatTail
Какой хороший меня псевдоним - можно и помурлыкать, а можно и когти показать.
Re: Robert Djabarov
На мой взгляд, лучше по-аглицки, чем "латиницей". Я в "латинице" вообще смысла уловить не могу.
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / LEFT JOIN - чудеса
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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