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

Откуда:
Сообщений: 526
Здравствуйте
У меня две таблицы: persons и staffs.
persons:
id name
1 name1
2 name2
3 name3
........

staffs:
personsid staff date
1 staff1 01.05.2000
1 staff2 01.06.2003
1 staff3 05.06.2004
2 staff4 01.06.1999
2 staff5 01.08.2006
...................

Надо получить такой тезультат:
Name1 staff3 05.06.2004
name2 staff5 01.08.2006
То есть имя человека и занимаемый должность.
Понятно, что это будет тот запись из второй таблицы, для которой personsid соответствует данного человаека и дата самое последнее (бпльшое)

Заранее спасибо, буду благодарен
23 май 06, 18:26    [2697897]     Ответить | Цитировать Сообщить модератору
 Re: Как составить правильный запрос ?  [new]
RENaissance
Member

Откуда: Муром->Москва
Сообщений: 10894

???
declare @persons table (id int, name varchar(10))
insert @persons values (1, 'name1')
insert @persons values (2, 'name2')
insert @persons values (3, 'name3')

declare @staffs table (personsid int, staff varchar(10), date datetime)
insert @staffs values (1, 'staff1', '01.05.2000')
insert @staffs values (1, 'staff2', '01.06.2003')
insert @staffs values (1, 'staff3', '05.06.2004')
insert @staffs values (2, 'staff4', '01.06.1999')
insert @staffs values (2, 'staff5', '01.08.2006')

select persons.name, staffs.staff, staffs.date
from @persons persons
inner join @staffs staffs on
  persons.id = staffs.personsid
where exists(select 1
             from @staffs
             where personsid = persons.id
             group by personsid
             having max(date) = staffs.date)



Posted via ActualForum NNTP Server 1.3

23 май 06, 18:35    [2697938]     Ответить | Цитировать Сообщить модератору
 Re: Как составить правильный запрос ?  [new]
seath
Member

Откуда: Путинград
Сообщений: 123
SELECT Persons.Name, Staffs.Staff, Staffs.Date
FROM Persons INNER JOIN Staffs ON
Persons.ID = Staffs.PersonsID
23 май 06, 18:35    [2697944]     Ответить | Цитировать Сообщить модератору
 Re: Как составить правильный запрос ?  [new]
Fine
Member

Откуда:
Сообщений: 526
seath
SELECT Persons.Name, Staffs.Staff, Staffs.Date
FROM Persons INNER JOIN Staffs ON
Persons.ID = Staffs.PersonsID


Нет, Вы мне не поняли, надо взять только один оз штатов данного человека
23 май 06, 18:40    [2697959]     Ответить | Цитировать Сообщить модератору
 Re: Как составить правильный запрос ?  [new]
Fine
Member

Откуда:
Сообщений: 526
RENaissance

select persons.name, staffs.staff, staffs.date
from @persons persons
inner join @staffs staffs on
  persons.id = staffs.personsid
where exists(select 1
             from @staffs
             where personsid = persons.id
             group by personsid
             having max(date) = staffs.date)


Твой вариант наверно будет работать, буду попробовать :)
23 май 06, 18:47    [2697983]     Ответить | Цитировать Сообщить модератору
 Re: Как составить правильный запрос ?  [new]
Fine
Member

Откуда:
Сообщений: 526
Нет товатищи :(
Не работает :(
Возможо я не правильно задавал вопрос, то есть вопрос не в ту форум я положил. У мея база МС Акцесс, наверно по этому не работает.
Если дтугие варианты есть - скажите пожалуйста....
24 май 06, 18:36    [2702426]     Ответить | Цитировать Сообщить модератору
 Re: Как составить правильный запрос ?  [new]
Hamlet
Member

Откуда: Armenia
Сообщений: 575
declare @persons table (id int, name varchar(10))
insert @persons values (1, 'name1')
insert @persons values (2, 'name2')
insert @persons values (3, 'name3')

declare @staffs table (personsid int, staff varchar(10), date datetime)
insert @staffs values (1, 'staff1', '01.05.2000')
insert @staffs values (1, 'staff2', '01.06.2003')
insert @staffs values (1, 'staff3', '05.06.2004')
insert @staffs values (2, 'staff4', '01.06.1999')
insert @staffs values (2, 'staff5', '01.08.2006')


select p.name, s.staff, s.date
from @persons p
	inner join @staffs s 
		on p.id = s.personsid
	left join @staffs s1
		on s.personsid = s1.personsid
			and s.date < s1.date
	where s1.date is null

Если интересуют и те сотрудники у которых должность неизвестно, то внутренее соединение нужно сделать внешним.
24 май 06, 18:48    [2702470]     Ответить | Цитировать Сообщить модератору
 Re: Как составить правильный запрос ?  [new]
Fine
Member

Откуда:
Сообщений: 526
Hamlet
select p.name, s.staff, s.date
from @persons p
	inner join @staffs s 
		on p.id = s.personsid
	left join @staffs s1
		on s.personsid = s1.personsid
			and s.date < s1.date
	where s1.date is null

А без знака "@" не возможно ?
Может быть проблема менно в том...
24 май 06, 18:52    [2702500]     Ответить | Цитировать Сообщить модератору
 Re: Как составить правильный запрос ?  [new]
pasha701
Member

Откуда: Дніпропетровськ
Сообщений: 231
declare @persons table (id int, name varchar(10))
insert @persons values (1, 'name1')
insert @persons values (2, 'name2')
insert @persons values (3, 'name3')

declare @staffs table (personsid int, staff varchar(10), date datetime)
insert @staffs values (1, 'staff1', '01.05.2000')
insert @staffs values (1, 'staff2', '01.06.2003')
insert @staffs values (1, 'staff3', '05.06.2004')
insert @staffs values (2, 'staff4', '01.06.1999')
insert @staffs values (2, 'staff5', '01.08.2006')


select p.name,
s.staff,
s.date
from @persons p inner join @staffs s on p.id = s.personsid
Where Not Exists(
Select 1
From @staffs S2
Where p.id = S2.personsid And
S2.date>s.date
)


Если в один день біло 2 должности, обе будут здесь.
Немного проще чем пред. запрос.
24 май 06, 18:59    [2702538]     Ответить | Цитировать Сообщить модератору
 Re: Как составить правильный запрос ?  [new]
Владимор Конев
Member

Откуда:
Сообщений: 3456
Fine
Заранее спасибо, буду благодарен
Решение для MS SQL SERVER 2005:
select *
  from (
          select persons.id,
                 persons.name,
                 staffs.staff,
                 staffs."DATE",
                 row_number() over(partition by persons.id 
                                       order by staffs."DATE" desc
                                  ) as rn
            from persons 
            left outer join 
                 staffs
              on persons.id = staffs.personsid
       )
 where rn = 1

Классическое решение, работающее на любых версиях:
select persons.id,
       persons.name,
       staffs.staff,
       staffs."DATE"
  from persons 
  left outer join 
       staffs
    on persons.id = staffs.personsid
  left outer join    
       staffs s1
    on s1.personsid = staffs.personsid
   and staffs."DATE" <= s1."DATE"
group by persons.id,
       persons.name,
       staffs.staff,
       staffs."DATE"
having count(1) = 1
25 май 06, 05:55    [2703432]     Ответить | Цитировать Сообщить модератору
 Re: Как составить правильный запрос ?  [new]
Владимор Конев
Member

Откуда:
Сообщений: 3456
Есть ещё совсем хулиганский вариант...
В нем будет ВСЕГО один джойн, ВСЕГО один скан таблицы persons, ВСЕГО один скан таблицы staffs, группировка полученого результата. Приэтом не будет никаких вложенных запросов, никаких EXISTS.
Но много-много преобразований данных из одного типа в другой и работа со строками.
25 май 06, 06:01    [2703433]     Ответить | Цитировать Сообщить модератору
 Re: Как составить правильный запрос ?  [new]
Евгений1234-5
Member

Откуда: г. Ангарск
Сообщений: 500
declare @persons table (id int, name varchar(10))
insert @persons values (1, 'name1')
insert @persons values (2, 'name2')
insert @persons values (3, 'name3')

declare @staffs table (persid int, staff varchar(10), dte datetime)
insert @staffs values (1, 'staff1', '01.05.2000')
insert @staffs values (1, 'staff2', '01.06.2003')
insert @staffs values (1, 'staff3', '05.06.2004')
insert @staffs values (2, 'staff4', '01.06.1999')
insert @staffs values (2, 'staff5', '01.08.2006')

select ts.persid,max(ts.dte)
from @staffs ts
group by ts.persid

select tp.*,tsfs.*
from @persons tp inner join (select ts.persid pid,max(ts.dte) as dte
from @staffs ts
group by ts.persid
) tsfs on tp.id=tsfs.pid

go
25 май 06, 09:37    [2703707]     Ответить | Цитировать Сообщить модератору
 Re: Как составить правильный запрос ?  [new]
aleks2
Guest
Владимор Конев
Есть ещё совсем хулиганский вариант...
В нем будет ВСЕГО один джойн, ВСЕГО один скан таблицы persons, ВСЕГО один скан таблицы staffs, группировка полученого результата. Приэтом не будет никаких вложенных запросов, никаких EXISTS.
Но много-много преобразований данных из одного типа в другой и работа со строками.


Ну и нах..н? А не проще ли:

select p.id,
        p.name,
        s.staff,
        X.[DATE]
from 
(select personsid, MAX([DATE]) [DATE] FROM staffs GROUP BY personsid) X
left outer join 
staffs S ON X.personsid=S.personsid AND X.[DATE]=S.[DATE]
LEFT OUTER JOIN
persons p
ON X.personsid=p.ID
25 май 06, 11:23    [2704348]     Ответить | Цитировать Сообщить модератору
 Re: Как составить правильный запрос ?  [new]
Владимор Конев
Member

Откуда:
Сообщений: 3456
aleks2
Ну и нах..н?
Именно поэтому я этот вариант даже приводить не стал, просто сказав, что он есть... :)

aleks2
А не проще ли:

select p.id,
        p.name,
        s.staff,
        X.[DATE]
from 
(select personsid, MAX([DATE]) [DATE] FROM staffs GROUP BY personsid) X
left outer join 
staffs S ON X.personsid=S.personsid AND X.[DATE]=S.[DATE]
LEFT OUTER JOIN
persons p
ON X.personsid=p.ID
Оно конечно проще...
НО!!! Просто, во-первых, многие (уж не знаю почему) до смерти боятся использовать подзапросы / встроенные представления / деривед таблицы / select from select (выбери название себе по вкусу), предпочитая делать все в "один селект", а во-вторых, есть такие сервера, которые просто не поддерживают вложенные запросы (к примеру MySQL до версии 4.1), в-третьих, предложить все возможные варианты решения автору топика, IMHO, гораздо лучше, чем оставить его в неведение о существовании этих решений...
25 май 06, 11:39    [2704463]     Ответить | Цитировать Сообщить модератору
 Re: Как составить правильный запрос ?  [new]
aleks2
Guest
Тута форум по MS SQL... с вытекающими последствиями.
25 май 06, 11:50    [2704541]     Ответить | Цитировать Сообщить модератору
 Re: Как составить правильный запрос ?  [new]
Владимор Конев
Member

Откуда:
Сообщений: 3456
aleks2
Тута форум по MS SQL... с вытекающими последствиями.
Это не мешает людям боятся подзапросов и селектов из них :)
25 май 06, 11:56    [2704565]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить