我想知道是否可以直接在SQL中执行以下操作。我有一个文本格式的列,其值用-
分隔。因此,示例行值可能看起来为1-42-9
。我想进行选择,以根据某种逻辑将-
之间的每个字符串替换为另一个字符串。例如,假设我的逻辑说每个等于42
的字符串都应该用ABC
代替,这将给我1-ABC-9
。可以在SELECT
语句中完成吗?
答案 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
结果为:-
如果您想进行更复杂的替换,请说您可以使用嵌套替换替换两个项目,请注意,这很繁琐,因为替换顺序很重要,例如用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)
使用substring
和case
,您可以执行以下操作:
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'
的列(因此,请确保它的可变长度为元素和涵盖1
与111
的情况),应该是:
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
(可能会更漂亮,但可以正常工作:))
这仅适用于具有由短划线分隔的3个元素的字符串列表
如果要在任何位置替换某个元素,只需对first_element
和third_element
应用相同的CASE语句
此外,您可以简单地执行以下操作:
replace('-'||id||'-','-42-','-ABC-')
-如果将字符串包装在另外的破折号中,则无论其位置(开始,中间,结束)如何,都可以搜索42