SQL Server-删除字符,除非在特定字符之前或之后

时间:2018-11-23 12:34:51

标签: sql-server tsql

让我们说我有一个像这样的数据集:

Data
I have 23, chickens, but no cats
I have 23, chickensx, but no cats
I have 23, chickens,x but no cats

我想删除所有逗号。除非在x之后或之前。 因此,在这种情况下,它应该变为:

Data
I have 23 chickens but no cats
I have 23 chickensx, but no cats
I have 23 chickens,x but no cats

有关如何执行此操作的任何想法/建议?我可以在一个记录中有多个逗号,在x后面或前面有多个逗号。

4 个答案:

答案 0 :(得分:2)

您可以使用多个REPLACE

SELECT col,
 REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
   col,',x,','#'),',x','~'),'x,','^'),',',''),'~',',x'),'^','x,'),'#',',x,')
FROM tab

db<>fiddle demo

答案 1 :(得分:2)

我不认为这种工作应该在数据库中,但是

CREATE TABLE T (DATA VARCHAR(100));

INSERT INTO T(DATA) VALUES 
('I have 23 , chickens, ,x xw, but no cats'),
('I have 23 , chickens, but no ,@, cats'),
('I have 23, chickens, but no cats'),
('I have 23, chickensx, but no cats'),
(', 23!, I have 23, chickens,x, but no cats'),
(' , I have 23, chickens,x but no cats ,x _, _'),
('x,abc , !, x,x,');

DECLARE @DATA VARCHAR(MAX) = '';

SELECT @DATA = STRING_AGG(DATA, CHAR(9))
FROM T;

WHILE (SELECT PATINDEX('%[^x,%],[^x,%]%', @DATA)) > 0
BEGIN
  SET @DATA = STUFF(@DATA, PATINDEX('%[^x,%],[^x,%]%', @DATA) + 1, 1, '');
END

SELECT *
FROM STRING_SPLIT(@DATA, CHAR(9));

返回:

+-------------------------------------------+
|                   value                   |
+-------------------------------------------+
| I have 23  chickens ,x xw but no cats     |
| I have 23  chickens but no @ cats         |
| I have 23 chickens but no cats            |
| I have 23 chickensx, but no cats          |
|  23! I have 23 chickens,x, but no cats    |
|   I have 23 chickens,x but no cats ,x _ _ |
| x,abc  ! x,x,                             |
+-------------------------------------------+

Demo

或通过调用REPLACE() 7次CHAR()函数

SELECT Data,
       REPLACE(
               REPLACE(
                       REPLACE(
                               REPLACE(
                                       REPLACE(
                                               REPLACE(
                                                       REPLACE(Data, ',x,', CHAR(1)),
                                                       ',x', CHAR(2)
                                                      ),
                                               'x,', CHAR(9)),
                                       ',', ''),
                               CHAR(1), ',x,'),
                       CHAR(2), ',x'),
               CHAR(9), 'x,') Results
FROM T;

顺序是从内到外(从内部替换到顶部替换)

  • 找到',x,'并将其替换为CHAR(1)
  • 找到',x',并与CHAR(2)保持联系。
  • 找到'x,'并将其替换为CHAR(9)
  • 找到所有','并将其替换为''
  • 找回',x,'
  • 找回',x'
  • 找回'x,'

Demo

答案 2 :(得分:1)

它不是特别漂亮,但是您可以使用REPLACE'x,''x,'的字符更改为其他字符,替换所有逗号,然后更改其他字符后退:

WITH VTE AS(
    SELECT String
    FROM (VALUES ('I have 23, chickens, but no cats'),
                 ('I have 23, chickensx, but no cats'),
                 ('I have 23, chickens,x but no cats'))V(String))
SELECT REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(String,'x,',CHAR(1)),',x',CHAR(2)),',',''),CHAR(2),',x'),CHAR(1),'x,') AS NewString
FROM VTE;

要注意的重要一件事是选择一个不会出现在字符串中的字符(因此,我选择CHAR(1)CHAR(2),因为它们不是“可键入的”字符)。 / p>

答案 3 :(得分:1)

要视情况而定。

作为一项一次性任务–“我需要处理大量数据” –您可以通过

序列来完成
  • 输入转义代码
  • 删除逗号
  • unescape转义码。

您可以查看数据,以确保选择不在数据集中的转义码。例如:

CREATE TABLE T (DATA VARCHAR(100));

INSERT INTO T(DATA) VALUES 
('I have 23 , chickens, ,x xw, but no cats'),
('I have 23 , chickens, but no ,@, cats'),
('I have 23, chickens, but no cats'),
('I have 23, chickensx, but no cats'),
(', 23!, I have 23, chickens,x, but no cats'),
(' , I have 23, chickens,x but no cats ,x _, _'),
('x,abc , !, x,x,'),
('I have 23 , chickens, but no cats'),
('I have 23!, chickens, but no cats'),
('chickens,x, and ,x,'),
(',x,x,')


Select
  Replace(
  Replace(
  Replace(
  Replace(
  Replace(
  Replace(
  Replace(Data,
        ',x,', '___[]___'),
        ',x' , '___[___'),
        'x,' , '___]___'),

         ',' , ''),

        '___]___' , 'x,'),
        '___[___' , ',x'),
        '___[]___' , ',x,')

from T

但是要将此操作作为对您不亲自检查的数据的可重复的可靠任务,那么@ Jeroen-Mostert关于CLR或ETL的观点是更好的选择。

您仍然可以使用粗制Replace(Replace(...来完成此操作。我认为。一定是

  • 选择一些转义字符
  • 转义每个转义字符(例如,将每个_ [ ]加倍)
  • 转义每个重要的序列,x, x, ,x
  • 删除逗号
  • 转义序列
  • 逃生转义符。

我认为总共有13个嵌套的Replaces