Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 использование top 1 в join  [new]
AlenaRo
Member

Откуда:
Сообщений: 21
Коллеги, подскажите есть селект, второй и третьий join выдает несколько значений, как то нужно взять только одну запись, скорее всего подойдет top 1, но вот как его использовать в join я не знаю, подскажите пожалуйста.

SELECT vpr_wk_type.Work_type,
		c.Auto_Card, c.Name As Last_Name_Ru, c.Name_i As First_Name_Ru,
		c.Name_o As Middle_Name_Ru, c.NetName As ShortName, c.EMail, c.First_Name,
		c.Last_Name, c.Second_Name As Middle_Name, c.Phone_1 As Phone_Work, c.Phone_2 As Phone_Mob,
		people.in_date As Start_Date, people.out_date As End_Date, people.Num_Tab,
		a.Name_appoint As Job_Title_Ru, a.job As Job_Title, 
		(CASE WHEN isnull(prl.prd,0)=0 THEN '0' ELSE convert(varchar,prl.prd,104) END) As Maternity,
		setup.Short_name As Company_Ru, setup.Addr_city As City_Ru,
		dbo.UDF_pr_tree_name(pr_current.Code_struct_name, ' / ') As Department_Ru, Name_eng As Company
from card c
left join (select  max(out_date)as od, auto_card from people group by auto_card )p on c.Auto_Card = p.Auto_Card 
left join (select  auto_card ,   min(sovm)as sv from people group by  auto_card order by sv)ps on ps.Auto_Card= p.Auto_Card 
left join people on p.Auto_Card = people.Auto_Card and p.od=people.out_date
left join pr_current on pr_current.pid = people.pid
left join Appointments a on a.Code_appoint = pr_current.Code_Appoint
left join (select pid, max(fromd)as prd from pr_leave where pr_leave.Code_Leave = 2 and getdate() between fromd and tod group by pid )prl ON 
prl.pid = people.pId

left join vpr_wk_type on pr_current.Work_Code= vpr_wk_type.work_code
left join setup on setup.id_firm = pr_current.id_Firm
WHERE pr_current.Flag_last = '*' 
22 ноя 12, 16:25    [13514306]     Ответить | Цитировать Сообщить модератору
 Re: использование top 1 в join  [new]
iap
Member

Откуда: Москва
Сообщений: 47194
AlenaRo
скорее всего подойдет top 1
То есть, Вы и сами не знаете, что должно получиться?
22 ноя 12, 16:27    [13514317]     Ответить | Цитировать Сообщить модератору
 Re: использование top 1 в join  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
подзапросы же умеете делать. так их и используйте select top 1 with ties from order by row_number() over (partition by поле по которому соединяем order by поле по которому надо взять первую запись) .
22 ноя 12, 16:34    [13514391]     Ответить | Цитировать Сообщить модератору
 Re: использование top 1 в join  [new]
Glory
Member

Откуда:
Сообщений: 104751
CROSS APPLY
22 ноя 12, 16:36    [13514404]     Ответить | Цитировать Сообщить модератору
 Re: использование top 1 в join  [new]
AlenaRo
Member

Откуда:
Сообщений: 21
iap
AlenaRo
скорее всего подойдет top 1
То есть, Вы и сами не знаете, что должно получиться?


Подойдет любая первая запись.
22 ноя 12, 17:03    [13514668]     Ответить | Цитировать Сообщить модератору
 Re: использование top 1 в join  [new]
iap
Member

Откуда: Москва
Сообщений: 47194
AlenaRo
iap
пропущено...
То есть, Вы и сами не знаете, что должно получиться?


Подойдет любая первая запись.
Вот это и странно.
22 ноя 12, 17:05    [13514680]     Ответить | Цитировать Сообщить модератору
 Re: использование top 1 в join  [new]
iap
Member

Откуда: Москва
Сообщений: 47194
iap
AlenaRo
пропущено...


Подойдет любая первая запись.
Вот это и странно.
Собственно говоря, что такое "первая запись" в Вашем понимании?
Я серьёзно спрашиваю, это не подколка, если что.
22 ноя 12, 17:06    [13514691]     Ответить | Цитировать Сообщить модератору
 Re: использование top 1 в join  [new]
icprog
Member

Откуда:
Сообщений: 166
Если уж "Подойдет любая первая запись", то может тогда
select  auto_card ,   min(sovm)as sv from people group by  auto_card order by sv

заменить на
select  min(auto_card) from people
22 ноя 12, 17:17    [13514779]     Ответить | Цитировать Сообщить модератору
 Re: использование top 1 в join  [new]
iap
Member

Откуда: Москва
Сообщений: 47194
icprog
Если уж "Подойдет любая первая запись", то может тогда
select  auto_card ,   min(sovm)as sv from people group by  auto_card order by sv

заменить на
select  min(auto_card) from people
Но "любая" и "первая" - это почти всегда взаимно исключающие понятия, Вам не кажется?
Исключения - пустая таблица или таблица с одной записью.
22 ноя 12, 17:21    [13514814]     Ответить | Цитировать Сообщить модератору
 Re: использование top 1 в join  [new]
icprog
Member

Откуда:
Сообщений: 166
iap,

Гадать мы можем сколько угодно ))
Подождем, что ответит автор на Ваш вопрос относительно первой записи
22 ноя 12, 17:27    [13514866]     Ответить | Цитировать Сообщить модератору
 Re: использование top 1 в join  [new]
AlenaRo
Member

Откуда:
Сообщений: 21
iap
iap
пропущено...
Вот это и странно.
Собственно говоря, что такое "первая запись" в Вашем понимании?
Я серьёзно спрашиваю, это не подколка, если что.


В таблице people есть поле out_date - это дата увольнения сотрудника, бывает такое, что по сотруднику две строки с одинаковыми датами увольнения, тогда функция max(out_date) оставляет две строки, нужна одна - любая. если пишу:

left join (select top 1 max(out_date)as od, auto_card from people group by auto_card, out_date order by out_date )p on c.Auto_Card = p.Auto_Card



то, вообще ни одного значения не выдает :-(, не пойму, что как сделать, что бы была только одна любая строка по человеку с одним увольнением
23 ноя 12, 09:23    [13517007]     Ответить | Цитировать Сообщить модератору
 Re: использование top 1 в join  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
AlenaRo
iap
пропущено...
Собственно говоря, что такое "первая запись" в Вашем понимании?
Я серьёзно спрашиваю, это не подколка, если что.


В таблице people есть поле out_date - это дата увольнения сотрудника, бывает такое, что по сотруднику две строки с одинаковыми датами увольнения, тогда функция max(out_date) оставляет две строки, нужна одна - любая. если пишу:

left join (select top 1 max(out_date)as od, auto_card from people group by auto_card, out_date order by out_date )p on c.Auto_Card = p.Auto_Card



то, вообще ни одного значения не выдает :-(, не пойму, что как сделать, что бы была только одна любая строка по человеку с одним увольнением

тогда можно так
outer apply(select top 1 max(p.out_date)as od, p.auto_card from people p where p.Auto_Card = c.Auto_Card group by p.auto_card, p.out_date order by p.out_date )p
23 ноя 12, 09:29    [13517047]     Ответить | Цитировать Сообщить модератору
 Re: использование top 1 в join  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 32167
AlenaRo
то, вообще ни одного значения не выдает
auto_card - это ИД человека? т.е. "по сотруднику две строки с одинаковыми датами увольнения" - это как, какие записи, два разных auto_card или один?
23 ноя 12, 09:30    [13517055]     Ответить | Цитировать Сообщить модератору
 Re: использование top 1 в join  [new]
AlenaRo
Member

Откуда:
Сообщений: 21
alexeyvg
AlenaRo
то, вообще ни одного значения не выдает
auto_card - это ИД человека? т.е. "по сотруднику две строки с одинаковыми датами увольнения" - это как, какие записи, два разных auto_card или один?


auto_card это уникальный ключ таблицы card, в таблице people он может повторятся, но для человека уникален.
23 ноя 12, 09:46    [13517160]     Ответить | Цитировать Сообщить модератору
 Re: использование top 1 в join  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 32167
AlenaRo
alexeyvg
пропущено...
auto_card - это ИД человека? т.е. "по сотруднику две строки с одинаковыми датами увольнения" - это как, какие записи, два разных auto_card или один?


auto_card это уникальный ключ таблицы card, в таблице people он может повторятся, но для человека уникален.
Зачем тогда top 1 ?

просто:
left join (
	select max(out_date)as od, auto_card 
	from people group by auto_card
	)p on c.auto_card = p.auto_card
Да, что это у вас там за "group by auto_card, out_date", зачем нужна группировка по дате??? наверное, в этом и ошибка.
23 ноя 12, 09:56    [13517209]     Ответить | Цитировать Сообщить модератору
 Re: использование top 1 в join  [new]
AlenaRo
Member

Откуда:
Сообщений: 21
alexeyvg,

иногда по сотруднику две строки с одинаковыми датами увольнения, тогда функция max(out_date) оставляет две строки, нужна одна - любая, видимо нужно top 1, но как-то не получается...
23 ноя 12, 10:29    [13517391]     Ответить | Цитировать Сообщить модератору
 Re: использование top 1 в join  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 32167
AlenaRo
иногда по сотруднику две строки с одинаковыми датами увольнения, тогда функция max(out_date) оставляет две строки, нужна одна
Два записи с одинаковыми out_date и auto_card?
И запрос:
select max(out_date)as od, auto_card 
from people group by auto_card
возвращает 2 одинаковые записи?
23 ноя 12, 10:32    [13517409]     Ответить | Цитировать Сообщить модератору
 Re: использование top 1 в join  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 32167
alexeyvg
AlenaRo
иногда по сотруднику две строки с одинаковыми датами увольнения, тогда функция max(out_date) оставляет две строки, нужна одна
Два записи с одинаковыми out_date и auto_card?
И запрос:
select max(out_date)as od, auto_card 
from people group by auto_card

возвращает 2 одинаковые записи?
Запрос естественно возвратит одну запись, а удваивание у вас будет в left join people:
left join (select  max(out_date)as od, auto_card from people group by auto_card )p on c.Auto_Card = p.Auto_Card 
left join people on p.Auto_Card = people.Auto_Card and p.od=people.out_date

В общем, внимательно смотрите схему, данные и запрос, отлаживайте запрос, постепенно убирая/добавляя join-ы - всё сразу увидите.
23 ноя 12, 10:37    [13517449]     Ответить | Цитировать Сообщить модератору
 Re: использование top 1 в join  [new]
_djХомяГ
Guest
возвращаясь к subquery и top 1
declare  @person table (id int, lastname varchar(100))
insert into @person 
select 1,'Иванов'
union all
select 2,'Петров'
union all
select 3,'Сидоров'

declare @pesrson_attr table (id int, date datetime)
insert into @pesrson_attr
select 1,'20120801'
union all
select 1,'20120101'
union all
select 2,'20120311'
union all
select 2,'20120311'


select p.*,(select top 1 date from @pesrson_attr pa where p.id=pa.id order by date desc)
from 
@person p
23 ноя 12, 10:37    [13517454]     Ответить | Цитировать Сообщить модератору
 Re: использование top 1 в join  [new]
AlenaRo
Member

Откуда:
Сообщений: 21
alexeyvg
alexeyvg
пропущено...
Два записи с одинаковыми out_date и auto_card?
И запрос:
select max(out_date)as od, auto_card 
from people group by auto_card

возвращает 2 одинаковые записи?
Запрос естественно возвратит одну запись, а удваивание у вас будет в left join people:
left join (select  max(out_date)as od, auto_card from people group by auto_card )p on c.Auto_Card = p.Auto_Card 
left join people on p.Auto_Card = people.Auto_Card and p.od=people.out_date

В общем, внимательно смотрите схему, данные и запрос, отлаживайте запрос, постепенно убирая/добавляя join-ы - всё сразу увидите.


Спасибо, поняла, что это не первые две таблицы дублирют данные, дальше разберусь.
23 ноя 12, 11:12    [13517723]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить