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

Откуда:
Сообщений: 340
Есть функция, которая принимает строковый параметр '1, 3, 5-15, 5a'

в результате получается колонка
1
3
5-15


как сделать, что бы если встречается 5-15 на выходе было
5
7
9
11
13
15
10 авг 09, 11:38    [7516480]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
Glory
Member

Откуда:
Сообщений: 104760
_unkind_


как сделать, что бы если встречается 5-15 на выходе было
5
7
9
11
13
15

А если встретится 6-11, то что должно быть на выходе ?
10 авг 09, 11:43    [7516509]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
_unkind_
Member

Откуда:
Сообщений: 340
Glory
_unkind_


как сделать, что бы если встречается 5-15 на выходе было
5
7
9
11
13
15

А если встретится 6-11, то что должно быть на выходе ?


может встретиться либо интервал четных, либо нечетных, тоесть
5-15
на выходе
5
7
9
11
13
15

6-12 на выходе
6
8
10
12
10 авг 09, 11:46    [7516529]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
declare @s varchar(10), @x xml
set @s = '5-15'
--set @s = '6-12'

set @x = '<root><item val="' + replace(@s, '-', '"/><item val="') + '"/></root>'


select number
  from (select max(v.value('@val', 'int')) as mx
              ,min(v.value('@val', 'int')) as mn
          from @x.nodes('/root/item') as t(v)
        ) as t
  join master..spt_values as p on p.number between t.mn and t.mx
 where type = 'P'
   and number % 2 = t.mn % 2

number
-----------
5
7
9
11
13
15

(6 row(s) affected)
10 авг 09, 11:50    [7516551]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
Glory
Member

Откуда:
Сообщений: 104760
И что будет при двух пересекающихся интервалах ?
10 авг 09, 11:50    [7516552]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
_unkind_
Glory
_unkind_


как сделать, что бы если встречается 5-15 на выходе было
5
7
9
11
13
15

А если встретится 6-11, то что должно быть на выходе ?


может встретиться либо интервал четных, либо нечетных, тоесть
5-15
на выходе
5
7
9
11
13
15

6-12 на выходе
6
8
10
12
Опять парсим адреса KLADR?
https://www.sql.ru/forum/actualthread.aspx?bid=1&tid=654546&hl=address
10 авг 09, 11:53    [7516569]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
_unkind_
Member

Откуда:
Сообщений: 340
Паганель
declare @s varchar(10), @x xml
set @s = '5-15'
--set @s = '6-12'

set @x = '<root><item val="' + replace(@s, '-', '"/><item val="') + '"/></root>'


select number
  from (select max(v.value('@val', 'int')) as mx
              ,min(v.value('@val', 'int')) as mn
          from @x.nodes('/root/item') as t(v)
        ) as t
  join master..spt_values as p on p.number between t.mn and t.mx
 where type = 'P'
   and number % 2 = t.mn % 2

number
-----------
5
7
9
11
13
15

(6 row(s) affected)


а если будет такой интервал 1/2-21 или 1-22
10 авг 09, 11:53    [7516571]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
Glory
И что будет при двух пересекающихся интервалах ?
Не понял. У автора вроде речь про один интервал
10 авг 09, 11:54    [7516576]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
_unkind_
а если будет такой интервал 1/2-21 или 1-22
_unkind_
может встретиться либо интервал четных, либо нечетных
Вы уж определитесь
10 авг 09, 11:56    [7516594]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
_unkind_
Member

Откуда:
Сообщений: 340
Паганель
_unkind_
а если будет такой интервал 1/2-21 или 1-22
_unkind_
может встретиться либо интервал четных, либо нечетных
Вы уж определитесь


это интервалы домов, тоесть может разное попадаться 1а-21 и т.д.
10 авг 09, 12:03    [7516655]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
1) таблица домов есть?
2) алгоритм определения попадания в диапазон по-русски напишите пожалуйста
10 авг 09, 12:07    [7516683]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
_unkind_
Member

Откуда:
Сообщений: 340
Паганель
1) таблица домов есть?
2) алгоритм определения попадания в диапазон по-русски напишите пожалуйста



в функцию входит строка - '32,34,34а,36,38.38а,40,42,42а,44,44а,46-50,50а,52-58'

на выходе
32
34
34а
36
38
38а
40
42
42а
44
44а
46-50
50а
52-58

нужно, если встречается интервал типа 46-50 раскатывало его 46 48 50
но иногда проскакивают интервалы типа тех, которые описаны выше

код функции
+

ALTER function [dbo].[fn_GetVarcharInRows]
(
@vchString varchar(max)
)
returns @tblResult table(Col varchar(max))
as
BEGIN

declare @intCount int
set @intCount = 1 -- указатель на текущий символ обрабатываемой строки

declare @vchValue varchar(max)
set @vchValue = '' -- переменная служит в виде буфера сохранения очередной
-- записи для результирующей таблицы

while @intCount <= len(@vchString) + 1
begin
-- если очередной символ не является разделителем, либо
-- не достигнут конец строки, то накапливаем в
-- в переменной значение для очередной строки
if substring(@vchString, @intCount, 1) not in (',', ';', '.', '')
set @vchValue = @vchValue + substring(@vchString, @intCount, 1)
else if substring(@vchString, @intCount, 1) in ('-')
begin
insert into @tblResult(col)
values('123')
set @vchValue = ''
end
else
begin
-- иначе сбрасываем накопленное значение в результирующую таблицу
if len (ltrim(rtrim(@vchValue))) > 0
begin
insert into @tblResult(col)
values(ltrim(rtrim(@vchValue)))
set @vchValue = ''
end
end
set @intCount = @intCount + 1
end

return

END
10 авг 09, 12:14    [7516745]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
это был ответ на первый мой вопрос или на второй?
10 авг 09, 12:16    [7516755]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
Сергей Мишин
Member

Откуда:
Сообщений: 376
_unkind_
а если будет такой интервал 1/2-21 или 1-22

как должны обрабатываться такие интервалы?
10 авг 09, 12:19    [7516783]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
_unkind_
Member

Откуда:
Сообщений: 340
Паганель
это был ответ на первый мой вопрос или на второй?


на второй,

на первый - таблица домов есть в excel формате
10 авг 09, 12:19    [7516784]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
_unkind_
нужно, если встречается интервал типа 46-50 раскатывало его 46 48 50

А если существует еще дом 48а, тогда так:
46
48
48а
50
правильно?
Полностью алгоритм "раскатывания" распишите, пожалуйста

И таблицу домов, наверное, надо здесь использовать (если нет 48-го дома, что ж его выдавать-то)
10 авг 09, 12:22    [7516811]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
_unkind_
Member

Откуда:
Сообщений: 340
Паганель
_unkind_
нужно, если встречается интервал типа 46-50 раскатывало его 46 48 50

А если существует еще дом 48а, тогда так:
46
48
48а
50
правильно?
Полностью алгоритм "раскатывания" распишите, пожалуйста

И таблицу домов, наверное, надо здесь использовать (если нет 48-го дома, что ж его выдавать-то)


пример интервала '32,34,34а,36,38.38а,40,42,42а,44,44а,46-50,50а,52а-58

если встречается 32,34,34а,36,38.38а, его раскатывает в
32
34
34а
36
38
38а

если попадается 46-50 то
46
48
50

если попадается 52а-58 то
52а
54
56
58

мы не знаем какие дома могут попасться в интервале(с буквами, с дробью), потому опускаем этот момент и пишем только первый или последний дом из интервала если присутствует буква или дробь

то что Вы дали выше не подходит только тем, что работает с int значениями, а здесь получаются уже строковые
10 авг 09, 12:29    [7516865]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
Сергей Мишин
Member

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

DECLARE @s varchar(100)
SET @s = '1/2-6, 3a-7, 9-13, 5a'

SELECT
	CASE WHEN i<>LEFT(OrigNum,len(i)) THEN cast(i AS varchar) ELSE OrigNum END 
	,s FromPeriod
FROM(
	SELECT
		s
		,IsNull(CASE WHEN s LIKE '%-%' THEN left(s,charindex('-',s)-1) END,s) OrigNum
		,CASE WHEN patindex('%[^0-9]%',s)>0 THEN left(s,patindex('%[^0-9]%',s)-1) END bi
		,CASE WHEN s LIKE '%-%' THEN substring(s,charindex('-',s)+1,3) END ei
	FROM(
		SELECT
			rtrim(ltrim(substring(s,i+1,charindex(',',s+',',i+1)-i-1))) s
		FROM
			(select ','+@s s) a
			,(
			SELECT
				row_number() OVER(ORDER BY a.i) i
			FROM
				(SELECT 1 i UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1) a
				,(SELECT 1 i UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1) b
				,(SELECT 1 i UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1) c
			) b
		WHERE
			substring(s,i,1)=','
		) a
	)a
	LEFT JOIN (
		SELECT
			row_number() OVER(ORDER BY a.i) i
		FROM
			(SELECT 1 i UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1) a
			,(SELECT 1 i UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1) b
			,(SELECT 1 i UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1) c
		) b ON (i BETWEEN  bi AND ei AND bi % 2 = i % 2) OR i = ei
10 авг 09, 12:47    [7517022]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
_unkind_
Member

Откуда:
Сообщений: 340
Сергей Мишин,

просто супер, то что надо, единственное не воспринимает "." как разделитель, но это пустяки

СПАСИБО ОГРОМНОЕ
10 авг 09, 12:51    [7517042]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
_unkind_
Паганель
_unkind_
нужно, если встречается интервал типа 46-50 раскатывало его 46 48 50

А если существует еще дом 48а, тогда так:
46
48
48а
50
правильно?
Полностью алгоритм "раскатывания" распишите, пожалуйста

И таблицу домов, наверное, надо здесь использовать (если нет 48-го дома, что ж его выдавать-то)


пример интервала '32,34,34а,36,38.38а,40,42,42а,44,44а,46-50,50а,52а-58

если встречается 32,34,34а,36,38.38а, его раскатывает в
32
34
34а
36
38
38а

если попадается 46-50 то
46
48
50

если попадается 52а-58 то
52а
54
56
58

мы не знаем какие дома могут попасться в интервале(с буквами, с дробью), потому опускаем этот момент и пишем только первый или последний дом из интервала если присутствует буква или дробь

то что Вы дали выше не подходит только тем, что работает с int значениями, а здесь получаются уже строковые
По моей-то ссылке ходили? И ссылки, которые там приводятся, смотрели?
Неужели Вы думаете, что Вы первый KLADR приводите в божеский вид?

Кстати, полезные идеи можно почерпнуть по этой теме не только на форуме Microsoft SQL.
Хорошо бы ещё поискать на этом сайте по всем форумам (Access, Delphi и др.)
По словам KLADR, КЛАДР и т.п.
10 авг 09, 12:52    [7517051]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
_unkind_
то что Вы дали выше не подходит только тем, что работает с int значениями, а здесь получаются уже строковые
declare @s varchar(10)
declare @s1 varchar(10), @s2 varchar(10)
declare @i1 varchar(10), @i2 varchar(10)
declare @a1 varchar(10), @a2 varchar(10)

set @s = '52а-58'
--set @s = '9-13'
--set @s = '1/2-21' -- для этого диапазона автор так и не сказал, что он хочет получить

select @s1 = left(@s, charindex('-', @s) - 1)
      ,@s2 = substring(@s, charindex('-', @s) + 1, 8000)

select @i1 = case when patindex('%[^0-9]%', @s1) > 0 
                  then left(@s1, patindex('%[^0-9]%', @s1) - 1)
                  else @s1 end
      ,@i2 = case when patindex('%[^0-9]%', @s2) > 0 
                  then left(@s2, patindex('%[^0-9]%', @s2) - 1)
                  else @s2 end

select @a1 = case when patindex('%[^0-9]%', @s1) > 0 
                  then substring(@s1, patindex('%[^0-9]%', @s1), 8000)
                  else '' end
      ,@a2 = case when patindex('%[^0-9]%', @s2) > 0 
                  then substring(@s2, patindex('%[^0-9]%', @s2), 8000)
                  else '' end

select cast(number as varchar(10))
       + case when number = cast(@i1 as int) then @a1
              when number = cast(@i2 as int) then @a2
              else '' end
  from master..spt_values
 where type = 'P'
   and number between cast(@i1 as int) and cast(@i2 as int)
   and number % 2 = cast(@i1 as int) % 2

--------------------
52а
54
56
58

(4 row(s) affected)
10 авг 09, 12:53    [7517063]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
_unkind_
Member

Откуда:
Сообщений: 340
Сергей Мишин
_unkind_,

DECLARE @s varchar(100)
SET @s = '1/2-6, 3a-7, 9-13, 5a'

SELECT
	CASE WHEN i<>LEFT(OrigNum,len(i)) THEN cast(i AS varchar) ELSE OrigNum END 
	,s FromPeriod
FROM(
	SELECT
		s
		,IsNull(CASE WHEN s LIKE '%-%' THEN left(s,charindex('-',s)-1) END,s) OrigNum
		,CASE WHEN patindex('%[^0-9]%',s)>0 THEN left(s,patindex('%[^0-9]%',s)-1) END bi
		,CASE WHEN s LIKE '%-%' THEN substring(s,charindex('-',s)+1,3) END ei
	FROM(
		SELECT
			rtrim(ltrim(substring(s,i+1,charindex(',',s+',',i+1)-i-1))) s
		FROM
			(select ','+@s s) a
			,(
			SELECT
				row_number() OVER(ORDER BY a.i) i
			FROM
				(SELECT 1 i UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1) a
				,(SELECT 1 i UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1) b
				,(SELECT 1 i UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1) c
			) b
		WHERE
			substring(s,i,1)=','
		) a
	)a
	LEFT JOIN (
		SELECT
			row_number() OVER(ORDER BY a.i) i
		FROM
			(SELECT 1 i UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1) a
			,(SELECT 1 i UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1) b
			,(SELECT 1 i UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1) c
		) b ON (i BETWEEN  bi AND ei AND bi % 2 = i % 2) OR i = ei




а все-таки, если разделителем служит ".", как это сделать, не могу ее сюда припаять никак
10 авг 09, 13:17    [7517212]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
_unkind_
Member

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

например такая строка 1-19,12а,36а.21-35,37,39-45,47,49,51,53,55,57,59,61,63,65,67,69,71,73,75,77,79,81.
10 авг 09, 13:19    [7517232]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
Сергей Мишин
Member

Откуда:
Сообщений: 376
_unkind_,
Предварительно '.' заменить на ',' :
DECLARE @s varchar(1000)
SET @s = '1-19,12а,36а.21-35,37,39-45,47,49,51,53,55,57,59,61,63,65,67,69,71,73,75,77,79,81'

SELECT
	CASE WHEN i<>LEFT(OrigNum,len(i)) THEN cast(i AS varchar) ELSE OrigNum END 
	,s FromPeriod
FROM(
	SELECT
		s
		,IsNull(CASE WHEN s LIKE '%-%' THEN left(s,charindex('-',s)-1) END,s) OrigNum
		,CASE WHEN patindex('%[^0-9]%',s)>0 THEN left(s,patindex('%[^0-9]%',s)-1) END bi
		,CASE WHEN s LIKE '%-%' THEN substring(s,charindex('-',s)+1,3) END ei
	FROM(
		SELECT
			rtrim(ltrim(substring(s,i+1,charindex(',',s+',',i+1)-i-1))) s
		FROM
			(select ','+replace(@s,'.',',') s) a --просто '.' заменить на ','
			,(SELECT number i FROM master..spt_values WHERE type = 'P') b
		WHERE
			substring(s,i,1) = ','
		) a
	)a
	LEFT JOIN (SELECT number i FROM master..spt_values WHERE type = 'P') b ON
		(i BETWEEN  bi AND ei AND bi % 2 = i % 2) OR i = ei
ORDER BY
	2,1
10 авг 09, 13:33    [7517340]     Ответить | Цитировать Сообщить модератору
 Re: помогите с функцией  [new]
_unkind_
Member

Откуда:
Сообщений: 340
Сергей Мишин,

spt_values что это за сис. таблица, что в ней хранится?
10 авг 09, 13:42    [7517391]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить