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

Откуда:
Сообщений: 76
Всем привет. Работаю с openquery через динамический скл. Формирую с помощью StuFF условия для IN (@stuff) .
Т.К. openquery хавает всего 8000 символов, нужно разбивать @stuff.
Вот так формирую строку:
SELECT @source=STUFF((SELECT ','+ CAST(line AS NVARCHAR(50)) + ''
FROM lines
order by line
for xml path('')), 1,1,'')
получаю что то типо такого :
10013014104124,10013014104247,10013015745313,10013020009477,10013047477468,10013047495549,10013050868701,10013053615783,10013055328312,10013061775357,10013062590478,10013074437715......

Вопрос: Можно ли как то формировать n-е кол-во таких строк, выбирая в каждую строку, топ 50 ?
Т.е. что бы было:
1-я строка:10013014104124,10013014104247,10013015745313,10013020009477,10013047477468
2-я строка:10013047477468,10013047495549,10013050868701,10013053615783,10013055328312
3-я строка:....

Спасибо
21 июл 15, 09:14    [17915424]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь с StuFF  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
DECLARE @lines TABLE (line VARCHAR(200))

INSERT INTO @lines (line)
VALUES
	('10013014104124'),('10013014104247'),('10013015745313'),
	('10013020009477'),('10013047477468'),('10013047495549'),
	('10013050868701'),('10013053615783'),('10013055328312'),
	('10013061775357'),('10013062590478'),('10013074437715')

DECLARE @cnt TINYINT = 5

;WITH cte AS 
(
	SELECT *, RowNum = ROW_NUMBER() OVER (ORDER BY 1/0) - ISNULL(NULLIF(ROW_NUMBER() OVER (ORDER BY 1/0) % @cnt, 0), @cnt)
	FROM @lines  
)
SELECT STUFF((
       	SELECT ', ' + line
       	FROM cte
		WHERE t.RowNum = cte.RowNum
       	FOR XML PATH('')), 1, 2, '')
FROM (
	SELECT DISTINCT RowNum
	FROM cte
) t


страшный итог таков:

------------------------------------------------------------------------------
10013014104124, 10013014104247, 10013015745313, 10013020009477, 10013047477468
10013047495549, 10013050868701, 10013053615783, 10013055328312, 10013061775357
10013062590478, 10013074437715


ps. можно конечно еще лаконичнее вашу задачу решить через cross apply. но думалка что-то больше думает о работе :)
21 июл 15, 10:33    [17915812]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь с StuFF  [new]
bananazury
Member

Откуда:
Сообщений: 76
круто. Спасибо!
21 июл 15, 12:58    [17916608]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь с StuFF  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
рад был помочь :)
21 июл 15, 13:09    [17916657]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь с StuFF  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
AlanDenton
OVER (ORDER BY 1/0)
Всё-таки, красивее
OVER (ORDER BY 0/0)
21 июл 15, 14:02    [17916955]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь с StuFF  [new]
bananazury
Member

Откуда:
Сообщений: 76
а кому не сложно разжевать эту строку?

SELECT *, RowNum = ROW_NUMBER() OVER (ORDER BY 1/0) - ISNULL(NULLIF(ROW_NUMBER() OVER (ORDER BY 1/0) % @cnt, 0), @cnt)

Спасибо
21 июл 15, 16:07    [17917604]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь с StuFF  [new]
Minamoto
Member

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

смотрите хелп по ROW_NUMBER, по %, а также выполните этот запрос по частям, чтобы посмотреть, что же там такого интересного происходит, например, так:

SELECT *, ROW_NUMBER() OVER (ORDER BY 1/0), ISNULL(NULLIF(ROW_NUMBER() OVER (ORDER BY 1/0) % @cnt, 0), @cnt)
	FROM @lines  
21 июл 15, 16:12    [17917630]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь с StuFF  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
собственно, разжевывать там особо нечего. есть обычная задача про островки, т.е. найти периоды когда были прерывания последовательностей

решить ее можно как Бог на душу положит. одним из наиболее кошерных вариантов для меня является нумерация и сдвиг относительно какой-то константы.

пример:

DECLARE @data TABLE (dt DATE PRIMARY KEY)

INSERT INTO @data (dt)
VALUES
	('20150101'),('20150102'),('20150103'),
	('20150104'),('20150106'),('20150107'),
	('20150108'),('20150110'),('20150112'),
	('20150113'),('20150114'),('20150115')

SELECT MIN(t.dt), MAX(t.dt)
FROM (
	SELECT *, gr = DATEDIFF(DAY, '19000101', dt) - ROW_NUMBER() OVER (ORDER BY dt)
	FROM @data
) t
GROUP BY t.gr


---------- ----------
2015-01-01 2015-01-04
2015-01-06 2015-01-08
2015-01-10 2015-01-10
2015-01-12 2015-01-15


в Вашем случае все тоже самое... нумеруем строки. 1/0 это константа которая говорит "типа дай мне строки в таком порядке как захочешь". поскольку у нас куча - вернет все также как мы все вставили.

% - целочисленное деление, которое позволяет нам сформировать группы.

пс. если кто работает в Плариуме, то такие задачки там любят на собеседовании задавать :)
21 июл 15, 16:39    [17917758]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь с StuFF  [new]
invm
Member

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

Берете любую функцию разбиения строки по разделитель. Например эту - 10586095
И переписываете все, имхо, менее экстравагантно и более понятно:
declare @t table (v varchar(200));

insert into @t (v)
values
 ('10013014104124'), ('10013014104247'), ('10013015745313'),
 ('10013020009477'), ('10013047477468'), ('10013047495549'),
 ('10013050868701'), ('10013053615783'), ('10013055328312'),
 ('10013061775357'), ('10013062590478'), ('10013074437715');

declare @cnt int = 5;

with s(l) as
(
 select stuff((
  select
   case when (row_number() over (order by (select 1)) - 1) % @cnt = 0 then '|' else ',' end + v
  from
   @t
  for xml path('')), 1, 1, '')
)
select
 t.Value
from
 s cross apply
 f_StrToTableEx(s.l, '|') t;
21 июл 15, 16:41    [17917770]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь с StuFF  [new]
bananazury
Member

Откуда:
Сообщений: 76
всем спасибо!)
21 июл 15, 16:53    [17917830]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь с StuFF  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
AlanDenton
поскольку у нас куча - вернет все также как мы все вставили.
Не богохульствуй, сын мой!
21 июл 15, 17:10    [17917900]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить