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

Откуда: из России
Сообщений: 901
Есть таблица с данными:
id val1 dt
----------- ------------------------------ -----------------------
1 t1 2012-02-01 00:00:00.000
2 t2 2012-02-01 15:00:00.000
3 t1 2012-02-01 16:00:00.000
4 t1 2012-02-03 00:00:00.000
5 t2 2012-02-04 00:04:00.000
6 t1 2012-02-06 00:00:00.000
7 t1 2012-02-03 12:00:00.000
8 t2 2012-04-01 12:00:00.000
9 t3 2012-02-01 00:00:00.000
10 t3 2012-02-02 12:00:00.000
11 t4 2012-02-01 00:05:00.000

Как можно выбрать для каждого элемента val1 последние к примеру 2 события по дате возрастания,
у меня пока вот такой запрос:
select * from (
select *, ROW_NUMBER() over(partition by val1 order by dt desc) as n from dbo.tbl_dt ) as t
where t.n<=2


результат:
id val1 dt n
----------- ------------------------------ ----------------------- --------------------
6 t1 2012-02-06 00:00:00.000 1
7 t1 2012-02-03 12:00:00.000 2
8 t2 2012-04-01 12:00:00.000 1
5 t2 2012-02-04 00:04:00.000 2
10 t3 2012-02-02 12:00:00.000 1
9 t3 2012-02-01 00:00:00.000 2
11 t4 2012-02-01 00:05:00.000 1

но когда будет таблица довольно большая, тос RO_Number() будет довольно долго отрабатывать, да и вобще какие варианты еще можно сделать?
15 фев 12, 15:39    [12096545]     Ответить | Цитировать Сообщить модератору
 Re: Выбрать n - последних событий для элементов  [new]
iljy
Member

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

CROSS/OUTER APPLY + SELECT TOP(2)
15 фев 12, 15:46    [12096603]     Ответить | Цитировать Сообщить модератору
 Re: Выбрать n - последних событий для элементов  [new]
Slava_Nik
Member

Откуда: из России
Сообщений: 901
iljy
Slava_Nik,

CROSS/OUTER APPLY + SELECT TOP(2)

это написать функцию с селектом топ(2) по убыванию, так?
понял спасибо. а еще как можно без функций.
15 фев 12, 16:25    [12097005]     Ответить | Цитировать Сообщить модератору
 Re: Выбрать n - последних событий для элементов  [new]
iljy
Member

Откуда:
Сообщений: 8711
Slava_Nik,
зачем функцию??
15 фев 12, 16:40    [12097189]     Ответить | Цитировать Сообщить модератору
 Re: Выбрать n - последних событий для элементов  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
Slava_Nik
iljy
Slava_Nik,

CROSS/OUTER APPLY + SELECT TOP(2)

это написать функцию с селектом топ(2) по убыванию, так?
понял спасибо. а еще как можно без функций.
А где здесь говорится о функции?
15 фев 12, 16:41    [12097192]     Ответить | Цитировать Сообщить модератору
 Re: Выбрать n - последних событий для элементов  [new]
Slava_Nik
Member

Откуда: из России
Сообщений: 901
так cross \ outer apply применяется же к функциям, возвращающее табличное вырадение, к значениям результата запроса. так же вроде
15 фев 12, 17:14    [12097539]     Ответить | Цитировать Сообщить модератору
 Re: Выбрать n - последних событий для элементов  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
Slava_Nik
так cross \ outer apply применяется же к функциям, возвращающее табличное вырадение, к значениям результата запроса. так же вроде
Нет, не так.
Не только к функциям.
15 фев 12, 17:17    [12097567]     Ответить | Цитировать Сообщить модератору
 Re: Выбрать n - последних событий для элементов  [new]
Slava_Nik
Member

Откуда: из России
Сообщений: 901
тогда можете пример скинуть какой нить, либо по этой скелет запроса набросать
15 фев 12, 17:41    [12097845]     Ответить | Цитировать Сообщить модератору
 Re: Выбрать n - последних событий для элементов  [new]
iljy
Member

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

https://www.sql.ru/forum/actualsearch.aspx?search=cross+apply&sin=0&bid=1&a=&ma=0&dt=-1&s=1&so=1
15 фев 12, 18:17    [12098246]     Ответить | Цитировать Сообщить модератору
 Re: Выбрать n - последних событий для элементов  [new]
el_sh
Member

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

DECLARE   @t TABLE(id int,val VARCHAR(2),dt datetime)
INSERT INTO @t (
	id,
	val,
	dt
) SELECT 1, 't1', '2012-02-01 00:00:00.000'
UNION SELECT 2 ,'t2', '2012-02-01 15:00:00.000'
UNION SELECT 3 ,'t1', '2012-02-01 16:00:00.000'
UNION SELECT 4 ,'t1', '2012-02-03 00:00:00.000'
UNION SELECT 5 ,'t2', '2012-02-04 00:04:00.000'
UNION SELECT 6 ,'t1', '2012-02-06 00:00:00.000'
UNION SELECT 7 ,'t1', '2012-02-03 12:00:00.000'
UNION SELECT 8 ,'t2', '2012-04-01 12:00:00.000'
UNION SELECT 9 ,'t3', '2012-02-01 00:00:00.000'
UNION SELECT 10 ,'t3', '2012-02-02 12:00:00.000'
UNION SELECT 11 ,'t4', '2012-02-01 00:05:00.000'


SELECT d.* FROM (
SELECT DISTINCT val  FROM @t) t
CROSS APPLY(SELECT TOP 2  * FROM @t tt WHERE t.val=tt.val ORDER BY  dt DESC)d

SELECT TOP 1 WITH TIES * FROM @t ORDER BY CASE WHEN RANK() OVER (PARTITION BY val ORDER BY dt DESC)>2 THEN 2 ELSE 1 END 


А это статистика по 1 и 2 запросу
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 5 ms.

(строк обработано: 7)

SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 1 ms.
15 фев 12, 18:24    [12098292]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить