使用SQL从字符串中删除不需要的字符

时间:2019-09-09 11:22:29

标签: sql sql-server tsql

我尝试通过查询从字符串中获取以下结果。但是它没有显示出准确的结果。

  • 字符串:ty-R
    期望的输出:ty

  • 字符串:tuy-R
    所需的输出:tuy

我尝试使用替换功能。但是我无法删除下一个连字符,因为我必须使用第一个连字符。

DECLARE @str NVARCHAR(MAX);
DECLARE @lpcounter INT;

SET @str = 'ty-R ';
SET @lpcounter = 0;

WHILE @lpcounter <= 26
BEGIN
    SET @str = REPLACE(@str, CHAR(65 + @lpcounter), '');
    SET @lpcounter = @lpcounter + 1;
END;

SELECT @str;

这只能通过查询完成吗?

4 个答案:

答案 0 :(得分:2)

你在这里

WITH C AS
(
SELECT REPLACE(
         TRANSLATE(V, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', REPLICATE(' ', 26) --Or SPACE(26)
         )
         , ' ', '') Res
FROM
(
  VALUES
  ('8-R1-WEL'),
  ('276-R1E')
) T(V)
)
SELECT CASE WHEN RIGHT(Res, 1) = '-'
            THEN LEFT(Res, LEN(Res) -1)
            ELSE Res
       END Result
FROM C;

Demo

最后,建议不要使用数据库中的其他编程语言来进行字符串操作。

答案 1 :(得分:0)

这将返回您在问题中指定的值:

select str, replace(left(str, charindex('-', str) + 2), 'R', '')
from (values ('8-R1-WEL'), ('276-R1E')) v(str);

您尚未表达逻辑,因此将执行以下操作:

  • 将前两个子字符串用连字符隔开。
  • 删除“ R”。

答案 2 :(得分:0)

这是一种使用patindex在字符串中查找字母字符,遍历该字符串然后使用字符串的长度形成循环以删除这些字符的方法。

let table = Table(rowData: [], frame: .zero, style: .plain)
  view = table
  table.isFetching = true
  Table.fetchData(range: table.paginationRange) { rowItem in
     DispatchQueue.main.async { [weak table] in
        table?.rowData += rowItem
        table?.reloadData()
        table?.paginationIndex += Table.paginationAmount // set the new pagination index
        table?.isFetching = false
     }
  }

答案 3 :(得分:0)

我喜欢@Sami的TRANSLATE Solution,如果我使用的是SQL Server 2017+,我可能会使用。另一个有效的选择是使用PatExclude8K(下面包含DDL)。

-- Sample Data
DECLARE @table TABLE (string VARCHAR(1000));
INSERT @table VALUES ('8-R1-WEL'),('276-R1E')

-- Solution
SELECT 
  OldString = t.string, 
  NewString = IIF(f.NewString LIKE '%-',SUBSTRING(f.NewString,0,LEN(f.NewString)),f.NewString)
FROM   @table AS t
CROSS APPLY dbo.PatExclude8K(t.string,'[^0-9-]') AS f;

结果:

OldString    NewString
------------ -------------
8-R1-WEL     8-1
276-R1E      276-1

PatExclude8K代码:

CREATE FUNCTION dbo.PatExclude8K
(
    @String VARCHAR(8000),
    @Pattern VARCHAR(50)
) 
/*******************************************************************************
 Purpose:
 Given a string (@String) and a pattern (@Pattern) of characters to remove, 
 remove the patterned characters from the string.

Usage:
--===== Basic Syntax Example
 SELECT CleanedString 
 FROM dbo.PatExclude8K(@String,@Pattern);

--===== Remove all but Alpha characters
 SELECT CleanedString 
 FROM dbo.SomeTable st
 CROSS APPLY dbo.PatExclude8K(st.SomeString,'%[^A-Za-z]%');

--===== Remove all but Numeric digits
 SELECT CleanedString
 FROM dbo.SomeTable st
 CROSS APPLY dbo.PatExclude8K(st.SomeString,'%[^0-9]%');

 Programmer Notes:
 1. @Pattern is not case sensitive (the function can be easily modified to make it so)
 2. There is no need to include the "%" before and/or after your pattern since since we 
    are evaluating each character individually

 Revision History:
 Rev 00 - 10/27/2014 Initial Development - Alan Burstein

 Rev 01 - 10/29/2014 Mar 2007 - Alan Burstein
 - Redesigned based on the dbo.STRIP_NUM_EE by Eirikur Eiriksson
   (see: http://www.sqlservercentral.com/Forums/Topic1585850-391-2.aspx)
 - change how the cte tally table is created 
 - put the include/exclude logic in a CASE statement instead of a WHERE clause
 - Added Latin1_General_BIN Colation
 - Add code to use the pattern as a parameter.

 Rev 02 - 11/6/2014
        - Added final performane enhancement (more cudo's to Eirikur Eiriksson)
        - Put 0 = PATINDEX filter logic into the WHERE clause

Rev 03 - 5/16/2015
        - Updated code to deal with special XML characters
*******************************************************************************/
RETURNS TABLE WITH SCHEMABINDING AS
RETURN
WITH
E1(N) AS (SELECT N FROM (VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) AS X(N)),
itally(N) AS 
(
  SELECT TOP(CONVERT(INT,LEN(@String),0)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
  FROM E1 T1 CROSS JOIN E1 T2 CROSS JOIN E1 T3 CROSS JOIN E1 T4
) 
SELECT NewString =
((
  SELECT SUBSTRING(@String,N,1)
  FROM iTally
  WHERE 0 = PATINDEX(@Pattern,SUBSTRING(@String COLLATE Latin1_General_BIN,N,1))
  FOR XML PATH(''),TYPE
).value('(text())[1]','varchar(8000)'));
GO