SQL Server 2005 Использование CHARINDEX() Чтобы разделить строку
Как я могу разбить следующую строку на основе символа '-'?
Итак, если бы у меня была эта строка: LD-23DSP-1430
Как я могу разбить его на отдельные столбцы следующим образом:
LD 23DSP 1430
Кроме того, есть ли способ разделить каждый символ на отдельное поле, если мне нужно (без '-')? Я пытаюсь найти способ заменить каждое письмо алфавитом НАТО.
Итак, это было бы..... Лима Дельта Двадцать Три Дельта Сьерра Папа Четырнадцать Тридцать.... в одном поле.
Я знаю, что могу получить левую сторону следующим образом:
LEFT(@item, CHARINDEX('-', @item) - 1)
Ответы
Ответ 1
Я бы точно не сказал, что это легко или понятно, но всего за два дефиса вы можете изменить строку и не слишком сложно:
with t as (select 'LD-23DSP-1430' as val)
select t.*,
LEFT(val, charindex('-', val) - 1),
SUBSTRING(val, charindex('-', val)+1, len(val) - CHARINDEX('-', reverse(val)) - charindex('-', val)),
REVERSE(LEFT(reverse(val), charindex('-', reverse(val)) - 1))
from t;
Помимо этого, и вы можете использовать split()
вместо этого.
Ответ 2
Вот небольшая функция, которая сделает для вас "кодировку НАТО":
CREATE FUNCTION dbo.NATOEncode (
@String varchar(max)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN (
WITH L1 (N) AS (SELECT 1 UNION ALL SELECT 1),
L2 (N) AS (SELECT 1 FROM L1, L1 B),
L3 (N) AS (SELECT 1 FROM L2, L2 B),
L4 (N) AS (SELECT 1 FROM L3, L3 B),
L5 (N) AS (SELECT 1 FROM L4, L4 C),
L6 (N) AS (SELECT 1 FROM L5, L5 C),
Nums (Num) AS (SELECT Row_Number() OVER (ORDER BY (SELECT 1)) FROM L6)
SELECT
NATOString = Substring((
SELECT
Convert(varchar(max), ' ' + D.Word)
FROM
Nums N
INNER JOIN (VALUES
('A', 'Alpha'),
('B', 'Beta'),
('C', 'Charlie'),
('D', 'Delta'),
('E', 'Echo'),
('F', 'Foxtrot'),
('G', 'Golf'),
('H', 'Hotel'),
('I', 'India'),
('J', 'Juliet'),
('K', 'Kilo'),
('L', 'Lima'),
('M', 'Mike'),
('N', 'November'),
('O', 'Oscar'),
('P', 'Papa'),
('Q', 'Quebec'),
('R', 'Romeo'),
('S', 'Sierra'),
('T', 'Tango'),
('U', 'Uniform'),
('V', 'Victor'),
('W', 'Whiskey'),
('X', 'X-Ray'),
('Y', 'Yankee'),
('Z', 'Zulu'),
('0', 'Zero'),
('1', 'One'),
('2', 'Two'),
('3', 'Three'),
('4', 'Four'),
('5', 'Five'),
('6', 'Six'),
('7', 'Seven'),
('8', 'Eight'),
('9', 'Niner')
) D (Digit, Word)
ON Substring(@String, N.Num, 1) = D.Digit
WHERE
N.Num <= Len(@String)
FOR XML PATH(''), TYPE
).value('.[1]', 'varchar(max)'), 2, 2147483647)
);
Эта функция будет работать даже на очень длинных строках и работает довольно хорошо (я запускал ее по 100 000-символьной строке, и она возвращалась в 589 мс). Вот пример того, как его использовать:
SELECT NATOString FROM dbo.NATOEncode('LD-23DSP-1430');
-- Output: Lima Delta Two Three Delta Sierra Papa One Four Three Zero
Я преднамеренно сделал его табличной функцией, поэтому он может быть встроен в запрос, если вы запускаете его для многих строк сразу, просто используйте CROSS APPLY
или оберните приведенный выше пример в круглых скобках, чтобы использовать его как значение в SELECT
(вы можете поместить имя столбца в позицию параметра функции).
Ответ 3
Попробуйте выполнить следующий запрос:
DECLARE @item VARCHAR(MAX) = 'LD-23DSP-1430'
SELECT
SUBSTRING( @item, 0, CHARINDEX('-', @item)) ,
SUBSTRING(
SUBSTRING( @item, CHARINDEX('-', @item)+1,LEN(@ITEM)) ,
0 ,
CHARINDEX('-', SUBSTRING( @item, CHARINDEX('-', @item)+1,LEN(@ITEM)))
),
REVERSE(SUBSTRING( REVERSE(@ITEM), 0, CHARINDEX('-', REVERSE(@ITEM))))
Ответ 4
USE [master]
GO
/****** this function returns Pakistan where as if you want to get ireland simply replace (SELECT SUBSTRING(@NEWSTRING,CHARINDEX('[email protected][email protected]$',@NEWSTRING)+5,LEN(@NEWSTRING))) with
SELECT @NEWSTRING = (SELECT SUBSTRING(@NEWSTRING, 0,CHARINDEX('[email protected][email protected]$',@NEWSTRING)))******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[FN_RETURN_AFTER_SPLITER]
(
@SPLITER varchar(max))
RETURNS VARCHAR(max)
AS
BEGIN
--declare @testString varchar(100),
DECLARE @NEWSTRING VARCHAR(max)
-- set @teststring = '@ram?eez(ali)'
SET @NEWSTRING = @SPLITER ;
SELECT @NEWSTRING = (SELECT SUBSTRING(@NEWSTRING,CHARINDEX('[email protected][email protected]$',@NEWSTRING)+5,LEN(@NEWSTRING)))
return @NEWSTRING
END
--select [dbo].[FN_RETURN_AFTER_SPLITER] ('[email protected][email protected]$Pakistan')
Ответ 5
Create FUNCTION [dbo].[fnSplitString]
(
@string NVARCHAR(200),
@delimiter CHAR(1)
)
RETURNS @output TABLE(splitdata NVARCHAR(10)
)
BEGIN
DECLARE @start INT, @end INT
SELECT @start = 1, @end = CHARINDEX(@delimiter, @string)
WHILE @start < LEN(@string) + 1 BEGIN
IF @end = 0
SET @end = LEN(@string) + 1
INSERT INTO @output (splitdata)
VALUES(SUBSTRING(@string, @start, @end - @start))
SET @start = @end + 1
SET @end = CHARINDEX(@delimiter, @string, @start)
END
RETURN
END**strong text**
Ответ 6
DECLARE @variable VARCHAR(100) = 'LD-23DSP-1430';
WITH Split
AS ( SELECT @variable AS list ,
charone = LEFT(@variable, 1) ,
R = RIGHT(@variable, LEN(@variable) - 1) ,
'A' AS MasterOne
UNION ALL
SELECT Split.list ,
LEFT(Split.R, 1) ,
R = RIGHT(split.R, LEN(Split.R) - 1) ,
'B' AS MasterOne
FROM Split
WHERE LEN(Split.R) > 0
)
SELECT *
FROM Split
OPTION ( MAXRECURSION 10000 );