2015-08-12 3 views
0

таблицы ввода имеет строки, как это:SQL заменить серийный номер для конкретного появления символа в строке

Col_Name 
--------------- 
YXNYNXYYZY 
YYZZY 
-- and 100's of rows 

Я хочу найти конкретное вхождение символа Y, и создать поле вывода, как это:

Col_Name 
---------------- 
1,4,7,8,10 
1,2,5 

Я пытаюсь найти решение с функциями sql, такими как replace, len, charindex и т. Д., Но неспособным прийти на выход. Пожалуйста помоги.

+0

Ваш вопрос, кажется, отсутствует. С какими проблемами вы сталкиваетесь при попытке выполнить это? – BSMP

+0

Что вы попробовали и почему это не сработало? включая любые сообщения об ошибках. –

+0

В SQL вы обычно хотите, чтобы каждый столбец (в каждой строке) содержал значение * one * (будь то строка, int и т. Д.). SQL Server имеет два типа данных *, предназначенные * для хранения нескольких значений - самих таблиц (в виде строк, для повторения экземпляров одного и того же «типа» значения) и XML. Вам нужен формат выходного сигнала, фиксированный в камне? –

ответ

0

Это решение работает, но вы должны рассмотреть возможность изменения модели, потому что этот aproach может быть медленным и не должен быть работой SQL Server.

declare @search char(1) = 'Y' 

; with input(string) as (
    Select * From (values('YXNYNXYYZY'), ('YYZZY')) as input(string) 
), find(id, string, pos) as (=> get 1 row each Y found and its position 
    select 0, string, CHARINDEX(@search, string, 0) From input 
    Where CHARINDEX(@search, string, 0) > 0 
    Union All 
    select id+1, string, CHARINDEX(@search, string, pos+1) From find 
    Where CHARINDEX(@search, string, pos+1) > 0 
) 
--Select * from find => 1 position per row 
Select STUFF(--=> concatenate all position by string 
    (
     Select ', ' + CAST([pos] AS Varchar(10)) 
     From find f 
     Where (string = r.string) 
     Order By string, id 
     For XML PATH(''),TYPE 
    ).value('(./text())[1]','Varchar(100)') 
    ,1,2,'') AS x 
From find r 
Group BY string 
0

с помощью функции мы можем довести эти значения

alter FUNCTION [dbo].[GetPosition] 
(
@txt varchar(max), 
@Pat varchar(max) 
) 
RETURNS 
@tab TABLE 
(
ID int 
) 
AS 
BEGIN 
Declare @pos int 
Declare @oldpos int 
Select @oldpos=0 
select @pos=patindex(@pat,@txt) 
while @pos > 0 and @oldpos<>@pos 
begin 
    insert into @tab Values (@pos) 
    Select @[email protected] 
    select @pos=patindex(@pat,Substring(@txt,@pos + 1,len(@txt))) + @pos 

end 

RETURN 
END 

GO 

Вызов функции

SELECT 
stuff(
(
    SELECT ','+ cast(ID as nvarchar(4)) FROM dbo.[GetPosition] ('YXNYNXYYZY','%Y%') FOR XML PATH('') 
),1,1,'') 
0

Это было бы тривиально сделать с помощью языка сценариев, как PHP или Python. Сбросьте весь набор данных в массив и проверьте каждое значение. Событие 100 строк не будет проблемой.

  1. Load the CsV File
  2. Поиск массив значений.

// псевдо-код (непроверенные)

$Data = str_getcsv('c:\data\dumpeddata.csv'); 

foreach ($Data as $LineNo => $LineDetails) { 
    foreach($LineDetails as $ColNo => $ColData){ 
    if (strpos($ColData , 'Y') !== false){ 
    $Found .= "\nLine:$LineNo,Col:$ColNo"; 
    } 
} 
} 
echo $Found; 

Вы будете удивлены тем, как быстро это работает.

0
declare @n int = (select charindex('Y',col_name,1) from tablename) 
declare @l int = (select len(col_name) from tablename) 
declare @res varchar(100) = '' 
while @n <= @l and (select charindex('Y',col_name,@n) from tablename) <> 0 
begin 
set @res = @res + cast(select charindex('Y',col_name,@n) from tablename as varchar) + ' ' 
set @n = (select charindex('Y',col_name,@n) from tablename) + 1 
end 
select @res 

Это дает вам представление. Если это нужно сделать многократно, лучше обернуть это в функцию.

Смежные вопросы