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

Откуда: Sergiev Posad
Сообщений: 2974
Добрый день.
Имеем
Microsoft SQL Server 2005 - 9.00.4035.00 (Intel X86)   Nov 24 2008 13:01:59   Copyright (c) 1988-2005 Microsoft Corporation  Developer Edition on Windows NT 5.2 (Build 3790: Service Pack 2) 

Есть две таблицы
create table t1(id int, date datetime, date2 datetime)
insert into t1(id, date)
select 1, '20090101' union all
select 1, '20090115' union all
select 1, '20090117' union all
select 2, '20090110' union all
select 2, '20090201' 

create table t2(id1 int, date datetime)
insert into t2(id1, date)
select 1, '20090102' union all
select 1, '20090105' union all
select 1, '20090106' union all
select 1, '20090107' union all
select 1, '20090109' union all
select 1, '20090110' union all
select 1, '20090112' union all
select 1, '20090115' union all
select 1, '20090116' union all
select 1, '20090119' union all
select 1, '20090120' union all
select 2, '20090102' union all
select 2, '20090110' union all
select 2, '20090112' union all
select 2, '20090115' union all
select 2, '20090120' union all
select 2, '20090123' union all
select 2, '20090205' 

в таблице 1 - 200 тыс.записей
в таблице 2 - 20 млн.записей

разных id в пределах 50 тыс

надо обновить поле date2 в таблице 1 максимальной датой из таблицы 2, которая находится между двумя соседними периодами. заданными в таблице 1 по одному id

т.е должно получится следующее
id date date2
1 '2009-01-01' '2009-01-12'
1 '2009-01-15' '2009-01-16'
1 '2009-01-17' '2009-01-20'
2 '2009-01-10' '2009-01-23'
2 '2009-02-01' '2009-02-05'


пока в голову приходит лишь
табдицу 1 связать с собой (left join + row_number )
а потом подзапросами (select top 1 ) искать и подставлять занчения из таблицы 2
боюсь, что при таких объемах, запрос будет выполнятся очень долго

Может кто-то предложит более элегантное решение

Спасибо

I Have Nine Lives You Have One Only
THINK!
28 авг 09, 08:55    [7588996]     Ответить | Цитировать Сообщить модератору
 Re: Возможные решения  [new]
aleks2
Guest
1. Заполняем в t1 второе поле
declare @t1 table (id int, date datetime, date2 datetime)
insert into @t1(id, date)
select 1, '20090101' union all
select 1, '20090115' union all
select 1, '20090117' union all
select 2, '20090110' union all
select 2, '20090201' 

update t SET date2=ISNULL((select MIN(date) FROM @t1 X WHERE X.id=T.ID AND X.date>T.Date), '30000101')
FROM @t1 T 

select * FROM @t1

2. Дальше все просто
declare @t2 table (id1 int, date datetime)
insert into @t2(id1, date)
select 1, '20090102' union all
select 1, '20090105' union all
select 1, '20090106' union all
select 1, '20090107' union all
select 1, '20090109' union all
select 1, '20090110' union all
select 1, '20090112' union all
select 1, '20090115' union all
select 1, '20090116' union all
select 1, '20090119' union all
select 1, '20090120' union all
select 2, '20090102' union all
select 2, '20090110' union all
select 2, '20090112' union all
select 2, '20090115' union all
select 2, '20090120' union all
select 2, '20090123' union all
select 2, '20090205' 

UPDATE T SET date2=TT.MaxDate
FROM @t1 T 
INNER JOIN
(select T1.ID, T1.Date, MAX(T2.Date) MaxDate
  FROM
   @t1 T1 INNER JOIN @t2 T2 ON T1.ID=T2.ID1 AND T1.Date<=T2.Date AND T2.Date<T1.date2
  GROUP BY T1.ID, T1.Date
) as TT
ON T.ID=TT.ID AND T.Date=TT.Date

select * FROM @t1
28 авг 09, 09:32    [7589054]     Ответить | Цитировать Сообщить модератору
 Re: Возможные решения  [new]
Алексей2003
Member

Откуда: Москва
Сообщений: 5645
а если нет между периодами строки, тогда что подставлять?

для спящего время бодрствования равносильно сну
28 авг 09, 09:59    [7589121]     Ответить | Цитировать Сообщить модератору
 Re: Возможные решения  [new]
HandKot
Member

Откуда: Sergiev Posad
Сообщений: 2974
ничего, если есть то вставляем, если нет то пусто

I Have Nine Lives You Have One Only
THINK!
28 авг 09, 10:07    [7589140]     Ответить | Цитировать Сообщить модератору
 Re: Возможные решения  [new]
Алексей2003
Member

Откуда: Москва
Сообщений: 5645
а вы пробовали select запустить? сколько он по времени выполняется (объединив оба запроса от aleks2).

для спящего время бодрствования равносильно сну
28 авг 09, 10:17    [7589165]     Ответить | Цитировать Сообщить модератору
 Re: Возможные решения  [new]
HandKot
Member

Откуда: Sergiev Posad
Сообщений: 2974
вот сейчас пробую
I Have Nine Lives You Have One Only
THINK!
28 авг 09, 10:21    [7589188]     Ответить | Цитировать Сообщить модератору
 Re: Возможные решения  [new]
Алексей2003
Member

Откуда: Москва
Сообщений: 5645
только 1ый запрос с row_number отработает точно быстрее.

для спящего время бодрствования равносильно сну
28 авг 09, 10:42    [7589287]     Ответить | Цитировать Сообщить модератору
 Re: Возможные решения  [new]
HandKot
Member

Откуда: Sergiev Posad
Сообщений: 2974
Спасибо всем.
После доработки запросов напильником (в задаче были упрощенные данные)

Запрос отработал за 6 мин, что, в принципе, очень неплохой результат

Особое спасибо aleks2


I Have Nine Lives You Have One Only
THINK!
28 авг 09, 11:50    [7589854]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить