在SQL中部分替换字符串

时间:2019-05-04 08:20:30

标签: sql sqlite

我想知道是否可以直接在SQL中执行以下操作。我有一个文本格式的列,其值用-分隔。因此,示例行值可能看起来为1-42-9。我想进行选择,以根据某种逻辑将-之间的每个字符串替换为另一个字符串。例如,假设我的逻辑说每个等于42的字符串都应该用ABC代替,这将给我1-ABC-9。可以在SELECT语句中完成吗?

4 个答案:

答案 0 :(得分:2)

如果该列包含height: '100%', width: '100%' 之类的值,并且您要搜索'1-42-9'以替换为'42',则必须考虑所有情况,例如:

  • 'ABC'在该列的开头
  • '42'在该列的中间
  • '42'在该列的结尾
  • '42'是该列的唯一值

可以用更复杂但更精确的方法来处理这4种情况:

'42'

请参见demo
对于这些值:

select substr(
  replace('-' || col || '-', '-42-', '-ABC-'), 
  2,
  length(replace('-' || col || '-', '-42-', '-ABC-')) - 2
) NewCol
from tablename;

结果是:

create table tablename (col TEXT);
insert into tablename (col) values
('1-42-9'),
('42-1-9'),
('9-1-42'),
('42'),
('1-100-9');

答案 1 :(得分:1)

  

这可以在SELECT语句中完成吗?

是的,您可以使用replace function

要做的只是做1个替换,您可以使用:-

SELECT replace(mycolumn,'-42-','ABC') AS mycolumn FROM mytable;

一个简单的单数替换示例是:-

DROP TABLE IF EXISTS mytable;
CREATE TABLE IF NOT EXISTS mytable (mycolumn);
INSERT INTO mytable VALUES ('1-42-9'),('1429'); -- add some data (one row to be changed, the other not to be changed)
SELECT replace(mycolumn,'-42-','ABC') AS mycolumn FROM mytable; -- Do the replace maintaing the column name

结果为:-

enter image description here

如果您想进行更复杂的替换,请说您可以使用嵌套替换替换两个项目,请注意,这很繁琐,因为替换顺序很重要,例如用XYZ替换-9并用ABC替换-42- -42-9变为1ABCXYZ,则可以使用:-

SELECT replace(replace(mycolumn,'-9','-XYZ'),'-42-','ABC') AS mycolumn FROM mytable;

如果要进行多次替换,只需将1替换为-42-替换为ABC或-43-替换为DEF或-44-替换为GHI,则可以使用CASE WHEN THEN END构造: -

SELECT
    CASE 
      WHEN instr(mycolumn,'-42-') THEN replace(mycolumn,'-42-','ABC')
      WHEN instr(mycolumn,'-43-') THEN replace(mycolumn,'-43-','DEF')
      WHEN instr(mycolumn,'-44-') THEN replace(mycolumn,'-44-','GHI')
      ELSE mycolumn
  END AS mycolumn
FROM mytable;

答案 2 :(得分:0)

使用substringcase,您可以执行以下操作:

select case when '1-42-9' like '%-42-%'
then replace('1-42-9','-42-', '-ABC-' )
else '1-42-9' end 

您需要编写列名,而不是'1-42-9'的静态值。

答案 3 :(得分:0)

与SQLite兼容的动态解决方案是嵌套substr和instr函数,以将列表拆分为元素,然后将替换逻辑应用于元素。

对于表strings的表id具有值'1-42-9''777-5-21''7-55-123'的列(因此,请确保它的可变长度为元素和涵盖1111的情况),应该是:

SELECT
 input 
,first_element || '-' ||
 CASE second_element 
    WHEN '42' THEN 'ABC'
    WHEN '5' THEN 'DEF'
    ELSE second_element
 END || '-' ||
 third_element as output
FROM (
    select 
    id as input,
    substr(
      id,
      1,
      instr(id,'-')-1
    ) as first_element,             
    substr(
      substr(id,instr(id,'-')+1,100),
      1,
      instr(substr(id,instr(id,'-')+1,100),'-')-1
    ) as second_element
    ,substr(
      substr(id,instr(id,'-')+1,100),
      instr(substr(id,instr(id,'-')+1,100),'-')+1,
      100
    ) as third_element
    from strings
) t       

fiddle

(可能会更漂亮,但可以正常工作:))

这仅适用于具有由短划线分隔的3个元素的字符串列表

如果要在任何位置替换某个元素,只需对first_elementthird_element应用相同的CASE语句

此外,您可以简单地执行以下操作:

replace('-'||id||'-','-42-','-ABC-')-如果将字符串包装在另外的破折号中,则无论其位置(开始,中间,结束)如何,都可以搜索42