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

Откуда:
Сообщений: 129
В табличке помимо прочих есть поля UserID и ChunkNo где второе делит логически табличку на кусочки по Х строчек. Основное условие что строчки с одним и тем же юзером не мог принадлежать разным чанкам. Т.е. должно быть так для чанка размером 2:
User Chunk
1 1
1 1
2 2
3 2
5 3
5 3
5 3
5 3

И еще, табличка может быть приличного размера, так что нужно быть осторожным.

Заранее спасибо.
8 фев 15, 15:23    [17234816]     Ответить | Цитировать Сообщить модератору
 Re: Порезать логически таблицу по критерию и размеру.  [new]
aleks2
Guest
declare @t table (i int, id int identity primary key clustered, k int)
declare @n int = 2;

insert @t (i) values
(1 )
,(1) 
,(2 )
,(3 )
,(5 )
,(5 )
,(5 )
,(5 )

declare @k int = 1, @rc int = 1;

while @rc > 0
begin

  update t set k = @k
    from ( select top(@n) with ties * from @t where id > isnull( ( select max(id) from @t where k is not null ), 0 )  order by i ) t;

  set @rc =@@ROWCOUNT;

  set @k = @k + 1;

end;

select i, k from @t
8 фев 15, 16:51    [17234929]     Ответить | Цитировать Сообщить модератору
 Re: Порезать логически таблицу по критерию и размеру.  [new]
o-o
Guest
у вас размер куска определяется количеством строк, в него входящих?
Daba
поля UserID и ChunkNo где второе делит логически табличку на кусочки по Х строчек.

тогда почему в кусок номер 3 размера 2 попало 4 строки?
8 фев 15, 17:04    [17234959]     Ответить | Цитировать Сообщить модератору
 Re: Порезать логически таблицу по критерию и размеру.  [new]
Daba
Member

Откуда:
Сообщений: 129
0-0
Потому что я не могу разделить одного юзера на два чанка!
Вот сам что придумал:
SELECT a
	, FIRST_VALUE(ChunkNo) OVER (
		PARTITION BY a ORDER BY ChunkNo
		)
FROM (
	SELECT a
		, (
			(
				ROW_NUMBER() OVER (
					ORDER BY a
					) - 1
				) / 2
			) + 1 AS ChunkNo
		, LAG(a, 1, 0) OVER (
			ORDER BY a
			) prev_a
	FROM #t
	) q

Но это для 2012 и дальше...
8 фев 15, 17:39    [17235039]     Ответить | Цитировать Сообщить модератору
 Re: Порезать логически таблицу по критерию и размеру.  [new]
Daba
Member

Откуда:
Сообщений: 129
Пардон, так понятней:
SELECT a
	, FIRST_VALUE(ChunkNo) OVER (
		PARTITION BY a ORDER BY ChunkNo
		) FixedChunkNo
FROM (
	SELECT a
		, (
			(
				ROW_NUMBER() OVER (
					ORDER BY a
					) - 1
				) / 2 -- ChunkSize!!!
			) + 1 AS ChunkNo
	FROM #t
	) q
8 фев 15, 17:42    [17235046]     Ответить | Цитировать Сообщить модератору
 Re: Порезать логически таблицу по критерию и размеру.  [new]
o-o
Guest
дошло :)
наверное по-русски это звучит так:
нужно организовать типа постраничного вывода,
размер страницы -- ChunkSize строк.
при этом ни один юзер не может быть "поделен" между страницами,
т.е. под таких юзеров размер страницы увеличивается ровно настолько, чтобы уместить.
а то по исходной формулировке задача просто не всегда имеет решение :)

а надо-то под 2008 что-ли?
8 фев 15, 18:21    [17235134]     Ответить | Цитировать Сообщить модератору
 Re: Порезать логически таблицу по критерию и размеру.  [new]
o-o
Guest
кстати, если FIRST_VALUE заменить на min (без order by),
будет все то же самое, но пойдет и под 2005.
только нумерация кусков "с дырками" получается в любом случае:
declare @n int = 2;
declare @t table (i int, id int identity primary key clustered)

insert @t (i) values
(1 )
,(1) 
,(2 )
,(3 )
,(5 )
,(5 )
,(5 )
,(5 )
,(5 )
,(6 )
;

with cte as(
SELECT i, (	(ROW_NUMBER() OVER (ORDER BY i) - 1) / @n ) + 1 AS ChunkNo
FROM  @t
) 

SELECT i, min(ChunkNo) OVER (	PARTITION BY i) FixedChunkNo
FROM cte
---
i	FixedChunkNo
1	1
1	1
2	2
3	2
5	3
5	3
5	3
5	3
5	3
6	5
8 фев 15, 19:16    [17235242]     Ответить | Цитировать Сообщить модератору
 Re: Порезать логически таблицу по критерию и размеру.  [new]
Daba
Member

Откуда:
Сообщений: 129
o-o,

:) Наверно по-русски действительно так :) !
Я типа того, не русский... Плёхо гофорит по руски. :)
Идею с MIN сейчас попробую.
Спасибо.
9 фев 15, 12:43    [17237934]     Ответить | Цитировать Сообщить модератору
 Re: Порезать логически таблицу по критерию и размеру.  [new]
Daba
Member

Откуда:
Сообщений: 129
Кстати, недостаток обоих решений в том что, т.к. второй PARTITION не учитывает поле ChunkNo то размер чанка может быть меньше желаемого...
9 фев 15, 13:06    [17238102]     Ответить | Цитировать Сообщить модератору
 Re: Порезать логически таблицу по критерию и размеру.  [new]
o-o
Guest
Daba,

да, добавим
insert @t (i) values
(1 )
,(1) 
,(2 )
,(3 )
,(5 )
,(5 )
,(5 )
,(5 )
,(5 )
,(6 )
,(7 )
,(8 )
;

и все, привет.

у меня тут полный капец интернету, но из дома поищу на инглише именно на paging,
наверняка все давно до нас придумано.

P.S. алексов вариант катит при любой раскладке
9 фев 15, 13:18    [17238169]     Ответить | Цитировать Сообщить модератору
 Re: Порезать логически таблицу по критерию и размеру.  [new]
Daba
Member

Откуда:
Сообщений: 129
0-0,
Если предположить что кол-во юзеров большое а кол-во строчек на каждого из них нет, то тогда не страшно: скажем при размере чанка в 1000, реальный размер будет скажем от 950-1050, что в принципе ок.

Вариант с циклом проблематичен, т.к. таблица может быть достаточно большой, где-то 1-10 миллионов записей.
9 фев 15, 14:14    [17238579]     Ответить | Цитировать Сообщить модератору
 Re: Порезать логически таблицу по критерию и размеру.  [new]
o-o
Guest
Daba,

ясно.
еще, плиз, версию сервера уточните все-таки
9 фев 15, 14:29    [17238672]     Ответить | Цитировать Сообщить модератору
 Re: Порезать логически таблицу по критерию и размеру.  [new]
Daba
Member

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

Спасибо.
9 фев 15, 19:18    [17240582]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить