[MSSQL2005] LEFT JOIN с 0..1 записью, без подзапроса
От: baranovda Российская Империя  
Дата: 10.02.10 08:08
Оценка:
Сабж. Затмение какое-то нашло, не могу сообразить, как это сделать.

Пример: человек имеет несколько документов.

Persons

Person_ID
----------
1
2
3
4

Documents

Person_ID | Document_ID
------------------------
1         | 1
1         | 2
2         | 3
2         | 4
2         | 5
3         | 6


В результирующей выборке должны присутствовать все идентификаторы из Persons и хотя бы один (пусть даже первый попавшийся) из Documents.

Подзапросами типа

select 
  p.Person_ID, 
  (select top 1 d.Document_ID from Documents d where d.Person_ID = p.Person_ID) as Document_ID
from Persons p


задача решается, но такими подзапросами нужно выгрести около 30 полей, и код становится неопрятненьким.
Re: [MSSQL2005] LEFT JOIN с 0..1 записью, без подзапроса
От: Овощ http://www.google.com
Дата: 10.02.10 08:20
Оценка: 2 (1)
Здравствуйте, baranovda, Вы писали:

B>задача решается, но такими подзапросами нужно выгрести около 30 полей, и код становится неопрятненьким.


Если я правильно все понял, то можно подзапросом "выгрести" не все 30 полей, а только один первичный ключ таблицы (вроде это Document_ID), а затем, для получения всех остальных полей (тоже из Documents?), сделать еще один left join полученной выборки (Person_ID, Document_ID) c этой же таблицей Documents по полю Document_ID.
Re[2]: [MSSQL2005] LEFT JOIN с 0..1 записью, без подзапроса
От: baranovda Российская Империя  
Дата: 10.02.10 08:40
Оценка: 1 (1)
Здравствуйте, Овощ, Вы писали:

О>Здравствуйте, baranovda, Вы писали:


B>>задача решается, но такими подзапросами нужно выгрести около 30 полей, и код становится неопрятненьким.


О>Если я правильно все понял, то можно подзапросом "выгрести" не все 30 полей, а только один первичный ключ таблицы (вроде это Document_ID), а затем, для получения всех остальных полей (тоже из Documents?), сделать еще один left join полученной выборки (Person_ID, Document_ID) c этой же таблицей Documents по полю Document_ID.


Вот ещё с CTE-шкой интересный способ.

http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=117459
Re: [MSSQL2005] LEFT JOIN с 0..1 записью, без подзапроса
От: sunsquirel США  
Дата: 10.02.10 09:20
Оценка:
Здравствуйте, baranovda, Вы писали:

B>Пример: человек имеет несколько документов.

B>задача решается, но такими подзапросами нужно выгрести около 30 полей, и код становится неопрятненьким.

А так нельзя?
select distinct
d.Person_ID, 
d.Document_ID 
from Documents d
Re: [MSSQL2005] LEFT JOIN с 0..1 записью, без подзапроса
От: Sinix  
Дата: 10.02.10 09:36
Оценка: 1 (1)
Здравствуйте, baranovda, Вы писали:

B>В результирующей выборке должны присутствовать все идентификаторы из Persons и хотя бы один (пусть даже первый попавшийся) из Documents.


Как-то так?

SELECT P.Persons_ID, MIN (Document_ID)
  FROM Persons P
    LEFT JOIN Documents D ON P.Persons_ID = D.Persons_ID
  GROUP BY P.Persons_ID;
Re[2]: [MSSQL2005] LEFT JOIN с 0..1 записью, без подзапроса
От: baranovda Российская Империя  
Дата: 10.02.10 09:44
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Как-то так?


Так тоже можно, но у меня тут случай посложнее Партишны справляются лучше
Re[3]: [MSSQL2005] LEFT JOIN с 0..1 записью, без подзапроса
От: Sinix  
Дата: 10.02.10 10:01
Оценка:
Здравствуйте, baranovda, Вы писали:

B>Так тоже можно, но у меня тут случай посложнее Партишны справляются лучше

Партишны? OVER() что ли?
Re[4]: [MSSQL2005] LEFT JOIN с 0..1 записью, без подзапроса
От: baranovda Российская Империя  
Дата: 10.02.10 11:25
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, baranovda, Вы писали:


B>>Так тоже можно, но у меня тут случай посложнее Партишны справляются лучше

S>Партишны? OVER() что ли?

Да, он самый
Re: [MSSQL2005] LEFT JOIN с 0..1 записью, без подзапроса
От: _d_m_  
Дата: 11.02.10 01:27
Оценка: 10 (3)
Здравствуйте, baranovda, Вы писали:

B>Сабж. Затмение какое-то нашло, не могу сообразить, как это сделать.


B>Подзапросами типа


B>
B>select 
B>  p.Person_ID, 
B>  (select top 1 d.Document_ID from Documents d where d.Person_ID = p.Person_ID) as Document_ID
B>from Persons p
B>


B>задача решается, но такими подзапросами нужно выгрести около 30 полей, и код становится неопрятненьким.


select
    *
from
    Persons p
        outer apply
    (select top 1
        *
    from
        Documents d
    where
        d.Person_ID = p.Person_ID
    order by
        ...
    ) as dd
Re[2]: [MSSQL2005] LEFT JOIN с 0..1 записью, без подзапроса
От: Sinix  
Дата: 11.02.10 02:06
Оценка:
Здравствуйте, _d_m_.

А чем ваш вариант отличается от left join?
Re[3]: [MSSQL2005] LEFT JOIN с 0..1 записью, без подзапроса
От: _d_m_  
Дата: 11.02.10 03:38
Оценка: 1 (1)
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, _d_m_.


S>А чем ваш вариант отличается от left join?


А если подумать? А если представить себе таблицу Documents с 30 полями — ф-ция min() здесь уже не проканает.
Re[4]: [MSSQL2005] LEFT JOIN с 0..1 записью, без подзапроса
От: Sinix  
Дата: 11.02.10 04:09
Оценка: 1 (1)
Здравствуйте, _d_m_

___>А если подумать? А если представить себе таблицу Documents с 30 полями — ф-ция min() здесь уже не проканает.

Протупил.
Re[2]: [MSSQL2005] LEFT JOIN с 0..1 записью, без подзапроса
От: baranovda Российская Империя  
Дата: 11.02.10 05:31
Оценка:
Здравствуйте, _d_m_, Вы писали:

___>
___>select
___>    *
___>from
___>    Persons p
___>        outer apply
___>    (select top 1
___>        *
___>    from
___>        Documents d
___>    where
___>        d.Person_ID = p.Person_ID
___>    order by
___>        ...
___>    ) as dd
___>


"Канфэтка"!
Re[3]: [MSSQL2005] LEFT JOIN с 0..1 записью, без подзапроса
От: _d_m_  
Дата: 11.02.10 06:16
Оценка:
Здравствуйте, baranovda, Вы писали:

B>Здравствуйте, _d_m_, Вы писали:


...
B>"Канфэтка"!

Отож. cross/outer apply вобще мощная штука
Re[4]: [MSSQL2005] LEFT JOIN с 0..1 записью, без подзапроса
От: yogi Россия  
Дата: 11.02.10 09:35
Оценка:
Здравствуйте, _d_m_, Вы писали:

___>Здравствуйте, baranovda, Вы писали:


B>>Здравствуйте, _d_m_, Вы писали:


___>...

B>>"Канфэтка"!

___>Отож. cross/outer apply вобще мощная штука


Штука то мощная, но имею по ней вопрос: она входит в стандарт SQL или это расширение MSSQL?
И вопрос второй, как оно работает физически: если посмотреть план запроса (сам посмотреть не могу, так как с MSSQL не работаю), то не выполняются ли там те же джоины-агрегации, или те же аналитические(оконные) функции (называемые в этом топике партишенами)?
Путь к сердцу женщины лежать не должен.
Re[5]: [MSSQL2005] LEFT JOIN с 0..1 записью, без подзапроса
От: _d_m_  
Дата: 11.02.10 17:22
Оценка:
Здравствуйте, yogi, Вы писали:

___>>Отож. cross/outer apply вобще мощная штука


Y>Штука то мощная, но имею по ней вопрос: она входит в стандарт SQL или это расширение MSSQL?


Как я понял — это не стандартное расширение.

Y>И вопрос второй, как оно работает физически: если посмотреть план запроса (сам посмотреть не могу, так как с MSSQL не работаю), то не выполняются ли там те же джоины-агрегации, или те же аналитические(оконные) функции (называемые в этом топике партишенами)?


Как джойны.
Re[2]: [MSSQL2005] LEFT JOIN с 0..1 записью, без подзапроса
От: VGn Россия http://vassilsanych.livejournal.com
Дата: 17.02.10 09:54
Оценка:
S>
S>SELECT P.Persons_ID, MIN (Document_ID)
S>  FROM Persons P
S>    LEFT JOIN Documents D ON P.Persons_ID = D.Persons_ID
S>  GROUP BY P.Persons_ID;
S>


top намного производительней min
... << RSDN@Home 1.2.0 alpha 4 rev. 1419>>
Re[2]: [MSSQL2005] LEFT JOIN с 0..1 записью, без подзапроса
От: Powerz Россия https://zagosk.in
Дата: 17.02.10 19:28
Оценка:
Здравствуйте, sunsquirel, Вы писали:

S>А так нельзя?

S>
S>select distinct
S>d.Person_ID, 
S>d.Document_ID 
S>from Documents d
S>


Неа, потому что Document_ID будут разные.
https://zagosk.in
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.