Определение минимальной даты нахождения клиента в сегменте

Alchenok
Дата: 28.01.2013 12:04:15
Всем доброе утро!
Прошу вас о помощи в решении задачи. Суть задачи - необходимо определить актуальный статус клиентов (оплата/просрочка) , а также минимальную дату вхождения в этот статус. Например, клиент Иванов на протяжении 6 месяцев находился в таких статусах: 15.01.2012 - оплата , 15.02.2012 - просрочка, 15.03.2012 - оплата, 15.04.2012 - оплата, 15.05.2012 - просрочка, 15.06.2012 - просрочка.
На выходе результат по столбцам будет следующим: Иванов/Просрочка/15.05.2012.
Alchenok
Дата: 28.01.2013 12:26:33
Соориентируйте в каком направлении двигаться..
Гавриленко Сергей Алексеевич
Дата: 28.01.2013 12:28:01
В сторону выполнения пункта 4 и 6 из http://www.sql.ru/forum/actualthread.aspx?tid=127456
iap
Дата: 28.01.2013 12:33:50
Alchenok,

действительно, Вам словами всё описать? Может, даже, в стихах?
И версию сервера не назвали. А от этого зависит вариант решения,
которых очень много (поиск по форуму это подтвердит).
_djХомяГ
Дата: 28.01.2013 12:39:18
для >=2005
set dateformat dmy
declare @t table 
(
 date        smalldatetime,
 status      int
 )
 
 insert into @t 
 select '15.02.2012',0  ----- 0 просрочка 
 union all
 select '15.03.2012',1  ------1 оплата 
 union all
 select '15.04.2012',1
 union all
 select '15.05.2012',0
 union all
 select '15.06.2012',0
 
 ;with cte 
 as
 (
    row_number() over (order by date) - row_number() over (partition by status order by date) as GR
 ,* from @t
 )
 select top 1 MIDATE,STATUS
 from 
 (
 select min(date) MIDATE ,max(date) MADATE,GR,status
 from cte 
 group by gr,status
 ) t order by MIDATE desc
 
aleks2
Дата: 28.01.2013 12:50:42
declare @t table(clientId int, date datetime, state char(1), primary key clustered(clientId, date))

insert @t
select 1, '20120115', 'о'
union all
select 1, '20120215', 'п'
union all
select 1, '20120315', 'о'
union all
select 1, '20120415', 'о'
union all
select 1, '20120515', 'п'
union all
select 1, '20120615', 'п'
union all
select 2, '20120115', 'п'
union all
select 2, '20120215', 'щ'
union all
select 2, '20120315', 'п'
union all
select 2, '20120415', 'о'
union all
select 2, '20120515', 'о'
union all
select 2, '20120615', 'о'


select *
from
	(
             select  *, row_number() over(partition by clientId order by date asc) n
	from
		(select *
		, row_number() over(partition by clientId, state order by date desc) rn 
		, row_number() over(partition by clientId  order by date desc) nr
		from @t 
		) X
	where rn = nr
	) Y
where n = 1
Добрый Э - Эх
Дата: 28.01.2013 20:33:23
+ < Как вариант под MS SQl Server 2012:
declare @t table(clientId int, date datetime, state char(1), primary key clustered(clientId, date))

insert @t
select 1, '20120115', 'o'
union all
select 1, '20120215', 'p'
union all
select 1, '20120315', 'o'
union all
select 1, '20120415', 'o'
union all
select 1, '20120515', 'p'
union all
select 1, '20120615', 'p'
union all
select 2, '20120115', 'p'
union all
select 2, '20120215', 'm'
union all
select 2, '20120315', 'p'
union all
select 2, '20120415', 'o'
union all
select 2, '20120515', 'o'
union all
select 2, '20120615', 'o'

select clientid, max(state) as last_state, min(date) as start_date 
  from (
         select *, sum(start_of_group) over(partition by clientid order by date desc) as grp_id 
           from (
                  select *, case when state = lag(state) over(partition by clientid order by date desc) 
                              then 0 else 1 
                            end as start_of_group
                    from @t
                ) v
       ) v
 where grp_id = 1
 group by clientid
online проверка на sqlfiddle.com
Reinmar
Дата: 29.01.2013 03:44:26
aleks2, Спасибо!
Добрый Э - Эх
Дата: 29.01.2013 06:32:02
aleks2, top 1 with ties решил не прикручивать? Так бы сэкономил один уровень вложенности:
+ < с TOP ... WITH TIES:
declare @t table(clientId int, date datetime, state char(1), primary key clustered(clientId, date))

insert @t
select 1, '20120115', 'o'
union all
select 1, '20120215', 'p'
union all
select 1, '20120315', 'o'
union all
select 1, '20120415', 'o'
union all
select 1, '20120515', 'p'
union all
select 1, '20120615', 'p'
union all
select 2, '20120115', 'p'
union all
select 2, '20120215', 'm'
union all
select 2, '20120315', 'p'
union all
select 2, '20120415', 'o'
union all
select 2, '20120515', 'o'
union all
select 2, '20120615', 'o'

select top 1 with ties *
  from (
         select *
              , row_number() over(partition by clientId, state order by date desc) rn 
              , row_number() over(partition by clientId  order by date desc) nr
           from @t 
       ) X
 where rn = nr
 order by row_number() over(partition by clientId order by date asc)
aleks2
Дата: 29.01.2013 06:47:39
Добрый Э - Эх
aleks2, top 1 with ties решил не прикручивать? Так бы сэкономил один уровень вложенности:

Мине уровней не жалко.