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

Откуда:
Сообщений: 70
Есть таблица с данными ПриказыПоМерчендайзерам. В таблице код клиента (поле Клиент_У) код мерчендайзера (поле Мерчендайзер_У) тип приказа (поле ТипПриказа с типами Принят, Уволен, Перевод) и дата приказа (поле ДатаПриказа). В зависимости от типа приказа ДатаПриказа используется для определения дат принятия и увольнения мерчендайзеров следующим образом:
1. Дата принятия мерчендайзера по текущему клиенту является датой увольнения предыдущего мерчендайзера по текущему клиенту.
2. Дата перевода мерчендайзера является датой его увольнения по предыдущему клиенту и датой принятия по текущему клиенту.
3. Ну а дата увольнения она и есть дата увольнения. :)

Собственно таблица с данными (Me_U ID-шник записи)
Me_UКлиент_УМерчендайзер_УТипПриказаДатаПриказа
111Принят01.01.2009
222Принят01.01.2009
333Принят01.01.2009
422Уволен01.03.2009
524Принят01.03.2009
631Перевод01.03.2009
715Принят01.03.2009


Примерный вид в котором необходимо представить данные
Клиент_УМерчендайзер_УНачалоПолномочийПрекращениеПолномочий
1101.01.200901.03.2009
2201.01.200901.03.2009
3301.01.200901.03.2009
2401.03.2009
3101.03.2009
1501.03.2009



Если рассмотреть ситуацию на примере мерчендайзера 1 то мерчендайзер был принят 01.01.2009 по клиенту 1 (запись в таблице где Me_U=1). Далее мерчендайзер 1 был переведен 01.03.2009 клиенту 3 (запись в таблице где Me_U=6) что определило дату его увольнения по клиенту 1 и дату принятия по клиенту 3. Видно так же что запись в таблице по мерчендайзеру 5 (где Me_U=7) как бы "дополнительно подтверждает" увольнение мерчендайзера 1 по клиенту 1. Понимаю что возможны и другие сложные случаи когда дата в записи (где Me_U=7) может оказать больше или меньше даты в записи (где Me_U=6) но такие неприятные моменты можно пока не брать в расчет :) интересует самый простой вариант решения без учета всяких нехороших случаев :)
Прошу подсказать как задача подобная решается при помощи запроса. Ну или дать ссылку на тему где подобные вопросы побсуждались уже :) Спасибо.
20 сен 09, 20:07    [7684494]     Ответить | Цитировать Сообщить модератору
 Re: Как решить эту задачу представления данных одним запросом?  [new]
thorn
Member

Откуда: Москва
Сообщений: 115
formalist,

LEFT OUTER JOIN по той-же таблице
21 сен 09, 02:29    [7684984]     Ответить | Цитировать Сообщить модератору
 Re: Как решить эту задачу представления данных одним запросом?  [new]
Ozzy-Osbourne
Member

Откуда: Balashikha
Сообщений: 139
Если мерчендайзерам дают поработать хотя бы один день (т.е. дата увольнения/перевода всегда строго больше даты приема), то попробуйте через left join + group by:
if object_id('tempdb..##t')>0 drop table ##t
create table ##t(id int identity, cl int, md int, ord varchar(10), dt datetime)
insert into ##t(cl,md,ord,dt) select 1,1,'hired','20090101'
insert into ##t(cl,md,ord,dt) select 2,2,'hired','20090101'
insert into ##t(cl,md,ord,dt) select 3,3,'hired','20090101'
insert into ##t(cl,md,ord,dt) select 2,2,'fired','20090301'
insert into ##t(cl,md,ord,dt) select 2,4,'hired','20090301'
insert into ##t(cl,md,ord,dt) select 3,1,'moved','20090301'
insert into ##t(cl,md,ord,dt) select 1,5,'hired','20090301'

select 
   cl_u=m1.cl,md_u=m1.md
  ,dt_beg=convert(char(10),m1.dt,104)
  ,dt_end=convert(char(10),min(m2.dt),104)
from 
  (select id,cl,md,ord,dt from ##t where ord<>'fired') m1
  left join ##t m2 
  on (
      m1.md=m2.md and m1.cl<>m2.cl and m2.ord<>'hired'
      or
      m1.cl=m2.cl and m2.md<>m1.md and m2.ord<>'fired' 
     )
     and m2.dt>m1.dt 
group by m1.cl,m1.md,m1.dt
order by dt_Beg,dt_End,cl_u,md_u
Result:
cl_umd_udt_begdt_end
1101.01.200901.03.2009
2201.01.200901.03.2009
3301.01.200901.03.2009
1501.03.2009NULL
2401.03.2009NULL
3101.03.2009NULL


ЗЫ. Забавная картина получается, если дата приема может быть равна дате увольнения, причём время ("чч:мм:сс") в базе не хранится. Тогда возможен случай, когда у какого-то клиента в один и тот же день поменялась куча мерчендайзеров, некоторые по схеме 'hired -> fired', а некоторые по схеме 'hired->moved'. В итоге, надо будет для такого клиента искать "последнего выжившего" у него мерча :-)
Ввиду того, что Вы попросили дать "самый простой вариант решения без учета всяких нехороших случаев", будем считать, что под словом "дата" на самом деле понимается дата+время ;-)
21 сен 09, 03:10    [7685002]     Ответить | Цитировать Сообщить модератору
 Re: Как решить эту задачу представления данных одним запросом?  [new]
formalist
Member

Откуда:
Сообщений: 70
Огромное спасибо за советы буду пробовать :)
21 сен 09, 13:56    [7687023]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить