How to obtain a string equals to each first letter of words in a sentence IN SQL

时间:2019-01-07 13:22:09

标签: sql-server tsql sql-server-2012

I have words separated with a space in a column like apple orange banana I need the first letters as the result will be something like :

aob

5 个答案:

答案 0 :(得分:1)

首先,分割文本。我推荐一些功能:

CREATE FUNCTION Split(@text nvarchar(MAX),@separator nvarchar(MAX))
RETURNS TABLE AS RETURN
WITH Indexed AS
(
    SELECT 1 N, CAST(1 AS bigint) S, CHARINDEX(@separator, @text, 1) E WHERE @text IS NOT NULL
    UNION ALL
    SELECT N+1, E+DATALENGTH(@separator)/2, CHARINDEX(@separator, @text, E+DATALENGTH(@separator)/2) FROM Indexed WHERE E>S
), Token AS
(
    SELECT N, SUBSTRING(@text, S, CASE WHEN E=0 THEN DATALENGTH(@text)/2 ELSE E-S END) T FROM Indexed
)
SELECT * FROM Token

如果您使用的是SQL 2016及更高版本,请改用STRING_SPLIT

然后,您可以选择每个单词的第一个字符并加入。请参见以下示例:

DECLARE @Sample TABLE (T nvarchar(100));
INSERT @Sample VALUES (N'apple orange banana'),(N'dog cat');

SELECT (SELECT SUBSTRING(T,1,1) [*] FROM Split(T,N' ') FOR XML PATH(''))
FROM @Sample

结果:

(no column name)
------
aob
dc

答案 1 :(得分:0)

Not the most elegant solution, but still, you can use recursive CTE to split a delimited string with unknown delimiters and FOR XML to put the strings back together:

WITH tests(id, str) AS (
    SELECT 1, 'apple orange banana' UNION ALL
    SELECT 2, 'marry jane'
), rcte AS (
    SELECT id, str, 0 AS pos
    FROM tests
    UNION ALL
    SELECT id, str, CHARINDEX(' ', str, pos + 1)
    FROM rcte
    WHERE CHARINDEX(' ', str, pos + 1) > 0
)
SELECT id, (
    SELECT SUBSTRING(str, pos + 1, 1)
    FROM rcte
    WHERE id = t.id
    FOR XML PATH('')
) initials
FROM rcte t
GROUP BY id

答案 2 :(得分:0)

使用少量XML的另一个选择。您还可以使用ParseName(),只要在字符串中捕获任何句点即可。

示例

Declare @YourTable table(ID int,LastName varchar(50),FirstName varchar(50))
Insert Into @YourTable values
(1,'Waston','Mary Jane')

Select A.ID
      ,NewValue = upper(
                      concat(
                            xmlData.value('/x[1]','varchar(1)')
                           ,xmlData.value('/x[2]','varchar(1)')
                           ,xmlData.value('/x[3]','varchar(1)')
                           ,xmlData.value('/x[4]','varchar(1)')
                           ,'.'
                           ,LastName
                       )
                   )
 From  @YourTable A
 Cross Apply ( values (convert(xml,'<x>' + replace(A.FirstName,' ','</x><x>')+'</x>' )) ) B(xmlData)

返回

ID  NewValue
1   MJ.WASTON
  

编辑-添加了ParseName()选项

Select A.ID
      ,NewValue = upper(concat(Pos1,Pos2,Pos3,Pos4,'.',LastName))
 From  @YourTable A
 Cross Apply (
                Select Pos1 = left(parsename(tStr,4),1)
                      ,Pos2 = left(parsename(tStr,3),1)
                      ,Pos3 = left(parsename(tStr,2),1)
                      ,Pos4 = left(parsename(tStr,1),1)
                 From  ( values(replace(FirstName,' ','.'))) B1(tStr)
             ) B

答案 3 :(得分:0)

如果您在数据库中声明REGEX函数(不是SQL SERVER的本机)。

使用regexp_replace

select regexp_replace('apple orange banana','(\\w)(\\w* ?)','$1')

返回

aob

答案 4 :(得分:0)

我认为最短的是:

这里有一个模型表,其中有两行来模拟您的问题:

DECLARE @mockup TABLE(ID INT IDENTITY,YourWords VARCHAR(100));
INSERT INTO @mockup VALUES('apple orange banana'),('one two three');

-这是查询:

SELECT m.ID
      ,REPLACE(Casted.query('for $w in /x return substring($w,1,1)').value('.','varchar(max)'),' ','')
FROM @mockup m
CROSS APPLY(SELECT CAST('<x>' + REPLACE(m.YourWords,' ','</x><x>') + '</x>' AS XML)) A(Casted);

背后的想法:
字符串apple orange banana转换为<x>apple</x><x>orange</x><x>banana</x>并转换为XML,从而可以使用XQuery
现在,我们通过简单的.query()语句在XML上使用FLWOR。它告诉引擎:遍历/x的每个值并仅返回第一个字母。用value()作为.调用XPath会返回值 in
我们需要最后一个REPLACE()来消除空格,否则空格将显示为a o b而不是aob