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

Откуда:
Сообщений: 24
Здравствуйте Всем!

Есть некая таблица с транзакциями, их начала и завершения (id, timestart, timestop).
Задается некоторый отрезок времени, который нужно разделить на заданные равные промежутки времени, например,
20:00:00-21:00:00 по 10 минут
20:00:00 20:10:00
20:10:00 20:20:00
20:20:00 20:30:00
20:30:00 20:40:00
20:40:00 20:50:00
20:50:00 21:00:00
После чего необходимо определить количество транзакций в каждом из отрезков.

Сейчас я делаю следующим образом:
set dateformat dmy
declare @dtstart datetime
declare @dtstop datetime
set @dtstart = '12.09.2012 20:00:00'
set @dtstop = '12.09.2012 21:00:00'

create table #t (t_dtstart datetime, t_dtstart_1 datetime, t_count int)
	while @dtstart < @dtstop
	begin
	insert into #t values
		(@dtstart, dateadd(mm, 10, @dtstart), dbo.fun_count (@dtstart, dateadd(mm, 10, @dtstart)))
	set @dtstart = dateadd(mm, 10, @dtstart)
	end
...
drop table #t

Можно ли обойтись без использования цикла?
12 сен 12, 21:49    [13154636]     Ответить | Цитировать Сообщить модератору
 Re: как обойтись без цикла?  [new]
invm
Member

Откуда: Москва
Сообщений: 9413
select
 dateadd(mi, (datediff(mi, @dtstart, t.dt) / 10) * 10, @dtstart),
 count(*)
from
 MyTable mt cross apply
 (select dt from (values (mt.timestart), (mt.timeend)) t(dt)) t
where
 t.dt between @dtstart and @dtend
group by
 datediff(mi, @dtstart, t.dt) / 10
order by
 dateadd(mi, (datediff(mi, @dtstart, t.dt) / 10) * 10, @dtstart);
12 сен 12, 23:13    [13154904]     Ответить | Цитировать Сообщить модератору
 Re: как обойтись без цикла?  [new]
aleks2
Guest
set dateformat dmy
declare @dtstart datetime
declare @dtstop datetime
set @dtstart = '12.09.2012 20:00:00'
set @dtstop = '12.09.2012 21:00:00'

-- правильный подход - только точки изменения числа транзакций в интервале
;with
times as (select timestart as t from [некая таблица с транзакциями] where timestart between @dtstart and @dtstop union select timestop from [некая таблица с транзакциями] where timestop between @dtstart and @dtstop )
,
counts as (select times.t, count(*) from times inner join [некая таблица с транзакциями] x on times.t between x.timestart and x.timestop group by times.t )
select * from counts order by t

-- ну... нашинковать по 10 мин тоже можно... только зачем?
;with
times as (select @dtstart t
union all
select dateadd(minute, 10, times.t) t from times where times.t<@dtstop
)
,
counts as (select times.t, count(*) from times inner join [некая таблица с транзакциями] x on times.t between x.timestart and x.timestop group by times.t )
select * from counts order by t
13 сен 12, 08:49    [13155440]     Ответить | Цитировать Сообщить модератору
 Re: как обойтись без цикла?  [new]
invm
Member

Откуда: Москва
Сообщений: 9413
В общем, ночью надо спать, а не запросы писать...
select
 @dtstart = dateadd(mi, (datediff(mi, 0, @dtstart) / 10) * 10, 0),
 @dtend = dateadd(mi, (datediff(mi, 0, dateadd(mi, 10, @dtend)) / 10) * 10, 0);

with x as
(
 select @dtstart as d
 union all
 select
  dateadd(mi, 10, d)
 from
  x
 where
  dateadd(mi, 10, d) <= @dtend
)
select
 x.d, count(mt.timestart)
from
 x left join
 @MyTable mt on x.d between mt.timestart and mt.timeend
group by
 x.d
option
 (maxrecursion 0);
13 сен 12, 10:27    [13155907]     Ответить | Цитировать Сообщить модератору
 Re: как обойтись без цикла?  [new]
jody
Member

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

Спасибо, но результаты ни с первым, ни со вторым запросом не сходятся.
13 сен 12, 11:11    [13156251]     Ответить | Цитировать Сообщить модератору
 Re: как обойтись без цикла?  [new]
invm
Member

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

Тогда выкладывайте скрипты создания таблиц, тестовый набор данных, ваш вариант запроса и требуемый результат.
13 сен 12, 11:20    [13156313]     Ответить | Цитировать Сообщить модератору
 Re: как обойтись без цикла?  [new]
jody
Member

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

Деление заданного промежутка на отдельные интервалы нужны для построения графика динамики транзакций.
Причем, надо учитывать, что одна транзакция могла начаться в предыдущий интервал времени, а закончиться в текущий, так же она могла закончиться и в следующие 10 минут, а возможно и могла начаться в текущие 10 минут и закончиться в следующие.
Возьмем пример:
Дана таблица транзакций:
1 12:59:42.1230000 13:00:29.8000000
2 12:59:53.2000000 13:07:27.6870000
3 13:00:00.6570000 13:00:41.5800000
4 13:01:17.0530000 13:01:18.0830000
5 13:02:53.2970000 13:03:23.8130000
6 13:03:25.8700000 13:03:40.8330000
7 13:05:20.0400000 13:06:52.4600000
8 13:06:12.5370000 13:06:38.2170000
9 13:06:22.4570000 13:06:23.4870000
10 13:08:31.1200000 13:09:41.6970000
...
Дан промежуток 13:00:00 - 14:00:00
Для более точного результата разобьем его поминутно
13:00:00 13:01:00 3
13:01:00 13:02:00 2
13:02:00 13:03:00 2
13:03:00 13:04:00 3
13:04:00 13:05:00 1
13:05:00 13:06:00 2
13:06:00 13:07:00 3
...
13 сен 12, 11:32    [13156413]     Ответить | Цитировать Сообщить модератору
 Re: как обойтись без цикла?  [new]
jody
Member

Откуда:
Сообщений: 24
Мой вариант:
set dateformat dmy
declare @dtstart datetime
declare @dtstop datetime
declare @dt int
set @dtstart = '06.09.2012 13:00:00'
set @dtstop = '06.09.2012 14:00:00'
set @dt = datediff(ss, @dtstart, @dtstop)


create table #t (t_dtstart datetime, t_dtstart_1 datetime, t_count int)
	while @dtstart < @dtstop
	begin
	insert into #t values
		(@dtstart, dateadd(mi, 1, @dtstart), dbo.fun_count (@dtstart, dateadd(mi, 1, @dtstart)))
	set @dtstart = dateadd(mi, 1, @dtstart)
	end
select t_dtstart, t_dtstart_1, t_count from #t
drop table #t

Ну и функция:
CREATE FUNCTION dbo.fun_count (@dtstart datetime, @dtstop datetime)
RETURNS int
WITH EXECUTE AS CALLER
AS
BEGIN
     DECLARE @count int
     
		select @count = count(Id)
		from [Таблица с транзакциями]
		where	(TimeStop > @dtstart) and (TimeStart < @dtstop)
     
     RETURN(@count)
END
GO
SET DATEFIRST 1
13 сен 12, 11:38    [13156461]     Ответить | Цитировать Сообщить модератору
 Re: как обойтись без цикла?  [new]
invm
Member

Откуда: Москва
Сообщений: 9413
declare @MyTable table (id int, timestart time, timeend time);
insert into @MyTable
values
(1, '12:59:42.1230000', '13:00:29.8000000'),
(2, '12:59:53.2000000', '13:07:27.6870000'),
(3, '13:00:00.6570000', '13:00:41.5800000'),
(4, '13:01:17.0530000', '13:01:18.0830000'),
(5, '13:02:53.2970000', '13:03:23.8130000'),
(6, '13:03:25.8700000', '13:03:40.8330000'),
(7, '13:05:20.0400000', '13:06:52.4600000'),
(8, '13:06:12.5370000', '13:06:38.2170000'),
(9, '13:06:22.4570000', '13:06:23.4870000'),
(10, '13:08:31.1200000', '13:09:41.6970000');

declare @interval int = 1, @dtstart time = '13:00', @dtend time = '14:00';

with x as
(
 select @dtstart as ds, dateadd(mi, @interval, @dtstart) de
 union all
 select
  dateadd(mi, @interval, ds), dateadd(mi, @interval, de)
 from
  x
 where
  dateadd(mi, @interval, de) <= @dtend
)
select
 x.ds, x.de, count(mt.id)
from
 x left join
 @MyTable mt on x.ds < mt.timeend and x.de >= mt.timestart
group by
 x.ds, x.de
order by
 x.ds
option
 (maxrecursion 0);
13 сен 12, 12:22    [13156825]     Ответить | Цитировать Сообщить модератору
 Re: как обойтись без цикла?  [new]
Anddros
Member

Откуда:
Сообщений: 1077
declare @t_tran table (id int, d1 varchar(50), d2 varchar(50))
insert @t_tran
values ('1','12:59:42.1230000','13:00:29.8000000'),
('2','12:59:53.2000000','13:07:27.6870000'),
('3','13:00:00.6570000','13:00:41.5800000'),
('4','13:01:17.0530000','13:01:18.0830000'),
('5','13:02:53.2970000','13:03:23.8130000'),
('6','13:03:25.8700000','13:03:40.8330000'),
('7','13:05:20.0400000','13:06:52.4600000'),
('8','13:06:12.5370000','13:06:38.2170000'),
('9','13:06:22.4570000','13:06:23.4870000'),
('10','13:08:31.1200000','13:09:41.6970000')

declare @dBeg datetime = '19000101 13:00:00', @dEnd datetime = '19000101 14:00:00', @iDiff int = 1

;with n as (select 0 n union all select 0),
nn as (select convert(varchar(12),d,108)dd1, convert(varchar(12),dateadd(mi,@iDiff,d),108)dd2
from (
select top (datediff(mi,@dBeg,@dEnd)/@iDiff) dateadd(mi,(row_number()over(order by (select 1))-1)*@iDiff,@dBeg) d from n n1, n n2, n n3, n n4, n n5, n n6, n n7
)t)
select dd1, dd2, count(t.id) 
from nn
left join @t_tran t on d1<=dd2 and dd1<=d2 --and 
group by dd1, dd2
Если есть таблица чисел, то можно не извращаться с row_number()over(order by (select 1))...from n n1, n n2, n..., а использовать ее
13 сен 12, 12:39    [13156943]     Ответить | Цитировать Сообщить модератору
 Re: как обойтись без цикла?  [new]
aleks2
Guest
jody
aleks2,

...

Орел, не учи меня жить. Лучше подучись.
set nocount on

declare @MyTable table (id int, timestart datetime, timeend datetime);

insert into @MyTable
values
(1, '12:59:42.123', '13:00:29.800')
insert into @MyTable
values
(2, '12:59:53.200', '13:07:27.687')
insert into @MyTable
values
(3, '13:00:00.657', '13:00:41.580')
insert into @MyTable
values
(4, '13:01:17.053', '13:01:18.083')
insert into @MyTable
values
(5, '13:02:53.297', '13:03:23.813')
insert into @MyTable
values
(6, '13:03:25.870', '13:03:40.833')
insert into @MyTable
values
(7, '13:05:20.040', '13:06:52.460')
insert into @MyTable
values
(8, '13:06:12.537', '13:06:38.217')
insert into @MyTable
values
(9, '13:06:22.457', '13:06:23.487')
insert into @MyTable
values
(10, '13:08:31.120', '13:09:41.697');

declare @interval int, @dtstart datetime, @dtend datetime;

select @interval = 1, @dtstart  = '13:00', @dtend  = '14:00';


;with
times as (select @dtstart t
union all
select dateadd(minute, @interval, times.t) t from times where times.t<@dtend
)
,
counts as (select times.t, count(*) cnt from times inner join @MyTable x on times.t between x.timestart and x.timeend group by times.t )
select * from counts order by t 
13 сен 12, 13:04    [13157148]     Ответить | Цитировать Сообщить модератору
 Re: как обойтись без цикла?  [new]
Anddros
Member

Откуда:
Сообщений: 1077
К вопросу о том, где не стоит использовать рекурсию:

with q as (select 1 n union all select n+1 from q where n<10000)
select * from q
option (maxrecursion 0)

(10000 row(s) affected)
 SQL Server Execution Times:
   CPU time = 515 ms,  elapsed time = 1299 ms.


with n as (select 0 n union all select 0),
n1 as (select 0n from n n1, n n2, n n3, n n4),
n2 as (select top 10000 row_number()over(order by (select 1))n  from n1 n1, n1 n2, n1 n3, n1 n4)
select * from n2

(10000 row(s) affected)
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 371 ms.

:)
13 сен 12, 13:17    [13157292]     Ответить | Цитировать Сообщить модератору
 Re: как обойтись без цикла?  [new]
jody
Member

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

Спасибо большое все сошлось, но работает он в разы медленнее, если интервал брать 1сек.
13 сен 12, 13:28    [13157417]     Ответить | Цитировать Сообщить модератору
 Re: как обойтись без цикла?  [new]
jody
Member

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

Спасибо, но The statement terminated. The maximum recursion 100 has been exhausted before statement completion.
13 сен 12, 13:44    [13157597]     Ответить | Цитировать Сообщить модератору
 Re: как обойтись без цикла?  [new]
jody
Member

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

Даже если option (maxrecursion 0) тоже медленно, час деленный посекундно - 24 сек. выполнения против 3 сек.
13 сен 12, 13:50    [13157652]     Ответить | Цитировать Сообщить модератору
 Re: как обойтись без цикла?  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1162
Anddros
К вопросу о том, где не стоит использовать рекурсию:
+

with q as (select 1 n union all select n+1 from q where n<10000)
select * from q
option (maxrecursion 0)

(10000 row(s) affected)
 SQL Server Execution Times:
   CPU time = 515 ms,  elapsed time = 1299 ms.


with n as (select 0 n union all select 0),
n1 as (select 0n from n n1, n n2, n n3, n n4),
n2 as (select top 10000 row_number()over(order by (select 1))n  from n1 n1, n1 n2, n1 n3, n1 n4)
select * from n2

(10000 row(s) affected)
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 371 ms.

:)


Клево!

Т.е. получиться должно как то так?
set nocount on

declare @MyTable table (id int, timestart datetime, timeend datetime);

insert into @MyTable
values
(1, '12:59:42.123', '13:00:29.800')
insert into @MyTable
values
(2, '12:59:53.200', '13:07:27.687')
insert into @MyTable
values
(3, '13:00:00.657', '13:00:41.580')
insert into @MyTable
values
(4, '13:01:17.053', '13:01:18.083')
insert into @MyTable
values
(5, '13:02:53.297', '13:03:23.813')
insert into @MyTable
values
(6, '13:03:25.870', '13:03:40.833')
insert into @MyTable
values
(7, '13:05:20.040', '13:06:52.460')
insert into @MyTable
values
(8, '13:06:12.537', '13:06:38.217')
insert into @MyTable
values
(9, '13:06:22.457', '13:06:23.487')
insert into @MyTable
values
(10, '13:08:31.120', '13:09:41.697');

declare @interval int, @dtstart datetime, @dtend datetime;

select @interval = 1, @dtstart  = '13:00', @dtend  = '14:00';


with n as (select 0 n union all select 0),
n1 as (select 0n from n n1, n n2, n n3, n n4),
n2 as (select top 10000 row_number()over(order by (select 1))n  from n1 n1, n1 n2, n1 n3, n1 n4)
select id, DATEADD(SECOND, n2.n * @interval - 1, timestart), DATEADD(SECOND, n2.n * @interval, timestart) from n2
cross join @MyTable t
where DATEADD(SECOND, n2.n, timestart) <= t.timeend
order by id, DATEADD(SECOND, n2.n * @interval - 1, timestart)
13 сен 12, 14:46    [13158235]     Ответить | Цитировать Сообщить модератору
 Re: как обойтись без цикла?  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1162
jody, точнее, вот так:

set nocount on

declare @MyTable table 
(id int, 
 timestart datetime, 
 timeend datetime);

insert into @MyTable (id, timestart, timeend)
values (1, '00:00:00.000', '23:59:59.000');

declare @interval int;

select @interval = 1;

with n as (select 0 n 
           union all 
           select 0),
     n1 as (select 0n 
              from n n1, 
                   n n2, 
                   n n3, 
                   n n4),
     n2 as (select row_number() over(order by (select 1))n  
              from n1 n1, 
                   n1 n2, 
                   n1 n3, 
                   n1 n4, 
                   n1 n5)
select id, 
       DATEADD(SECOND, n2.n * @interval - 1, timestart), 
       DATEADD(SECOND, n2.n * @interval, timestart) 
  from n2
       cross join @MyTable t
 where DATEADD(SECOND, n2.n * @interval, timestart) <= t.timeend
 order by id, DATEADD(SECOND, n2.n * @interval - 1, timestart)


У меня суточный интервал делится на секундные за 4 секунды.
13 сен 12, 14:56    [13158347]     Ответить | Цитировать Сообщить модератору
 Re: как обойтись без цикла?  [new]
HandKot
Member

Откуда: Sergiev Posad
Сообщений: 2996
Minamoto
jody, точнее, вот так:

set nocount on

declare @MyTable table 
(id int, 
 timestart datetime, 
 timeend datetime);

insert into @MyTable (id, timestart, timeend)
values (1, '00:00:00.000', '23:59:59.000');

declare @interval int;

select @interval = 1;

with n as (select 0 n 
           union all 
           select 0),
     n1 as (select 0n 
              from n n1, 
                   n n2, 
                   n n3, 
                   n n4),
     n2 as (select row_number() over(order by (select 1))n  
              from n1 n1, 
                   n1 n2, 
                   n1 n3, 
                   n1 n4, 
                   n1 n5)
select id, 
       DATEADD(SECOND, n2.n * @interval - 1, timestart), 
       DATEADD(SECOND, n2.n * @interval, timestart) 
  from n2
       cross join @MyTable t
 where DATEADD(SECOND, n2.n * @interval, timestart) <= t.timeend
 order by id, DATEADD(SECOND, n2.n * @interval - 1, timestart)


У меня суточный интервал делится на секундные за 4 секунды.

а у меня есть таблица чисел .....
13 сен 12, 15:27    [13158754]     Ответить | Цитировать Сообщить модератору
 Re: как обойтись без цикла?  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1162
HandKot
+
Minamoto
jody, точнее, вот так:

set nocount on

declare @MyTable table 
(id int, 
 timestart datetime, 
 timeend datetime);

insert into @MyTable (id, timestart, timeend)
values (1, '00:00:00.000', '23:59:59.000');

declare @interval int;

select @interval = 1;

with n as (select 0 n 
           union all 
           select 0),
     n1 as (select 0n 
              from n n1, 
                   n n2, 
                   n n3, 
                   n n4),
     n2 as (select row_number() over(order by (select 1))n  
              from n1 n1, 
                   n1 n2, 
                   n1 n3, 
                   n1 n4, 
                   n1 n5)
select id, 
       DATEADD(SECOND, n2.n * @interval - 1, timestart), 
       DATEADD(SECOND, n2.n * @interval, timestart) 
  from n2
       cross join @MyTable t
 where DATEADD(SECOND, n2.n * @interval, timestart) <= t.timeend
 order by id, DATEADD(SECOND, n2.n * @interval - 1, timestart)


У меня суточный интервал делится на секундные за 4 секунды.

а у меня есть таблица чисел .....

Эмм, это я неправильно постановку задачи понял :) В таком случае мне добавить нечего. Поигрался - этот вариант дает такую ще производительность, как и CTE.
13 сен 12, 15:49    [13159032]     Ответить | Цитировать Сообщить модератору
 Re: как обойтись без цикла?  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1162
Minamoto
Эмм, это я неправильно постановку задачи понял :) В таком случае мне добавить нечего. Поигрался - этот вариант дает такую ще производительность, как и CTE.


Хотя... Не совсем. Берем исходные данные:

declare @MyTable table (id int, timestart datetime, timeend datetime);
insert into @MyTable
values
(1, '12:59:42.123', '13:00:29.800'),
(2, '12:59:53.200', '13:07:27.687'),
(3, '13:00:00.657', '13:00:41.580'),
(4, '13:01:17.053', '13:01:18.083'),
(5, '13:02:53.297', '13:03:23.813'),
(6, '13:03:25.870', '13:03:40.833'),
(7, '13:05:20.040', '13:06:52.460'),
(8, '13:06:12.537', '13:06:38.217'),
(9, '13:06:22.457', '13:06:23.487'),
(10, '13:08:31.120', '13:09:41.697');

declare @interval int, @dtstart datetime, @dtend datetime;

select @interval = 1, @dtstart  = '13:00:00', @dtend  = '13:59:59';


И берем два варианта исполнения:

Вариант 1:
with n as (select 0 n 
           union all 
           select 0),
     n1 as (select 0n 
              from n n1, 
                   n n2, 
                   n n3, 
                   n n4),
     n2 as (select row_number() over(order by (select 1))n  
              from n1 n1, 
                   n1 n2, 
                   n1 n3, 
                   n1 n4, 
                   n1 n5)
select DATEADD(SECOND, n2.n * @interval - 1, @dtstart), 
       DATEADD(SECOND, n2.n * @interval, @dtstart)
       ,COUNT(mt.id)
  from n2
         left join @MyTable mt
               on mt.timestart < DATEADD(SECOND, n2.n * @interval - 1, @dtstart) and mt.timeend > DATEADD(SECOND, n2.n * @interval, @dtstart) 
 where DATEADD(SECOND, n2.n * @interval, @dtstart) <= @dtend
 group by DATEADD(SECOND, n2.n * @interval - 1, @dtstart), 
       DATEADD(SECOND, n2.n * @interval, @dtstart), n
       order by n;


и вариант 2:
with cte as (select @dtstart as dtstart, DATEADD(SECOND, @interval, @dtstart) as dtend
              union all
              select cte.dtend,
                     DATEADD(SECOND, @interval, cte.dtend)
                from cte
                     where DATEADD(SECOND, @interval, cte.dtend) <= @dtend)
select cte.dtstart, cte.dtend, COUNT(mt.id) 
  from cte
       left join @MyTable mt
               on mt.timestart < cte.dtend and mt.timeend > cte.dtstart
 group by cte.dtstart, cte.dtend 
option (maxrecursion 0);



Если интервал равен часу, то с большим преимуществом выигрывает вариант с CTE:

Вариант 1:
(строк обработано: 3599)

SQL Server Execution Times:
CPU time = 1014 ms, elapsed time = 501 ms.

Вариант 2:
(строк обработано: 3599)

SQL Server Execution Times:
CPU time = 124 ms, elapsed time = 116 ms.

Но если взять интервал - сутки, то первый вариант становится более эффективным:

select @interval = 1, @dtstart  = '00:00:00', @dtend  = '23:59:59';


Вариант 1:
(строк обработано: 86399)

SQL Server Execution Times:
CPU time = 2387 ms, elapsed time = 3994 ms.

Вариант 2:
(строк обработано: 86399)

SQL Server Execution Times:
CPU time = 2589 ms, elapsed time = 4560 ms.
13 сен 12, 16:01    [13159152]     Ответить | Цитировать Сообщить модератору
 Re: как обойтись без цикла?  [new]
Anddros
Member

Откуда:
Сообщений: 1077
Minamoto
...
И берем два варианта исполнения:
...

Ужас... Это ж надо было так извратить...

У мну
1 час:

Вариант 1 - CPU time = 760 ms
Вариант 2 - CPU time = 121 ms
Вариант 3:
declare @interval int, @dtstart datetime, @dtend datetime;

select @interval = 1, @dtstart  = '13:00:00', @dtend  = '13:59:59';

with n as (select 0 n 
           union all 
           select 0),
     n1 as (select 0n 
              from n n1, 
                   n n2, 
                   n n3, 
                   n n4),
     n2 as (select top (datediff(ss,@dtstart,@dtend)/@interval) row_number()over(order by (select 1))-1 n  
              from n1 n1, 
                   n1 n2, 
                   n1 n3, 
                   n1 n4, 
                   n1 n5),
	n3 as (select n,dateadd(ss,n,@dtstart)d1, dateadd(ss,n+@interval,@dtstart)d2 from n2)
select d1,d2,(select count(*) from @MyTable mt where mt.timestart <= d2 and d1<=mt.timeend) 
from n3
order by n
CPU time = 20 ms

1 сутки:
Вариант 1 - CPU time = 2364 ms
Вариант 2 - CPU time = 2724 ms
Вариант 2 - CPU time = 1331 ms
13 сен 12, 23:37    [13161420]     Ответить | Цитировать Сообщить модератору
 Re: как обойтись без цикла?  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1162
Anddros
Minamoto
...
И берем два варианта исполнения:
...

Ужас... Это ж надо было так извратить...

"...я только учусь..." (с).

Спасибо за более верный вариант :)
14 сен 12, 11:20    [13163017]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить