SQLite:如何选择字符串的一部分?

hjzp0vay  于 2023-04-21  发布在  SQLite
关注(0)|答案(3)|浏览(187)

存在包含文件名的表列:image1.jpg,image12.png,script.php,.htaccess,...
我只需要选择文件扩展名。我更喜欢这样做:

SELECT DISTINCT SUBSTR(column,INSTR('.',column)+1) FROM table

但我的SQLite版本不支持INSTR。
有没有不使用INSTR函数的方法来实现它?

rnmwe5a2

rnmwe5a21#

下面是只选择文件扩展名的查询(经过测试和验证)。您的文件名可以包含任意数量的.字符-它仍然可以工作
从table_name中选择distinct replace(column_name,rtrim(column_name,replace(column_name,'.','')),'');
column_name是包含文件名的列的名称(文件名可以有多个.
table_name是表的名称

wlp8pajw

wlp8pajw2#

试试ltrim(X, Y)函数,这就是the doc说的:
ltrim(X,Y)函数返回一个字符串,该字符串是通过从X的左侧删除Y中出现的任何和所有字符而形成的。
列出所有的字母表作为第二个参数,类似于

SELECT ltrim(column, "abcd...xyz1234567890") From T

这将删除从左到.的所有字符。如果您需要不带点的扩展名,则使用SUBSTR。当然,这意味着文件名不能包含超过一个点。
但我认为在执行查询的代码中提取扩展更容易和更安全。

pvcm50d1

pvcm50d13#

使用SQLite版本3.38.0的json函数也可以实现这一点。
replace(column_name, rtrim(column_name, replace(column_name, '.', '' ) ), '')方法相比,这里的优点是您只需要提到column_name一次。

select distinct json_extract(json('{"s":["'||replace(column_name,'.','","')||'"]}'), '$.s[#-1]') from table_name;

下面是一些比较,包括处理没有扩展名的文件路径:

CREATE TEMP TABLE t (fn TEXT);
insert into t values (NULL);
insert into t values ('');
insert into t values ('a');
insert into t values ('abc');
insert into t values ('abc.def');
insert into t values ('abc.d.s.edrs');

SELECT
  fn AS full_filename,
  replace(fn, rtrim(fn, replace(fn, '.', '' ) ), '') AS option_a,
  json_extract(json('{"s":["'||replace(fn,'.','","')||'"]}'), '$.s[#-1]') AS option_b,
  CASE WHEN fn LIKE '%.%' THEN replace(fn, rtrim(fn, replace(fn, '.', '' ) ), '') ELSE NULL END AS option_c,
  CASE WHEN fn LIKE '%.%' THEN json_extract(json('{"s":["'||replace(fn,'.','","')||'"]}'), '$.s[#-1]') ELSE NULL END AS option_d
FROM t;

使用.headers on.mode column,输出如下:

full_filename  option_a    option_b    option_c    option_d
-------------  ----------  ----------  ----------  ----------

a              a           a
abc            abc         abc
abc.def        def         def         def         def
abc.d.s.edrs   edrs        edrs        edrs        edrs

相关问题