SQL Server 使用charindex()和子字符串函数进行负索引

zkure5ic  于 2023-01-25  发布在  其他
关注(0)|答案(3)|浏览(147)

我有一个列,其中包含以下格式的数据:

Field Name
123_456_ABC_DEF
12_34_456_XYZ_PQR
LMN_OPQ_123_456

在每种情况下,我需要,最后两个数据块,即.

ABC_DEF
XYZ_PQR
123_456

有没有办法使用charindex(),从字符串的右侧开始计数'_'

dtcbnfnu

dtcbnfnu1#

这里有一个不可读的和有点疯狂的方式做它:-)

-- DDL and sample data population, start
DECLARE @tbl TABLE (tokens VARCHAR(256));
INSERT @tbl VALUES
('123_456_ABC_DEF'),
('12_34_456_XYZ_PQR'),
('LMN_OPQ_123_456');

SELECT REVERSE(LEFT(REVERSE(tokens),CHARINDEX('_',REVERSE(tokens),CHARINDEX('_',REVERSE(tokens))+1)-1))
FROM @tbl

基本上就是反转文本,向前搜索,然后在结尾处反转....(SQL Server T-SQL)

nkoocmlb

nkoocmlb2#

请尝试以下解决方案。
它基于通过XML和XQuery的 * 标记化 *。
值得注意的要点:

  • CROSS APPLY正在将输入标记为XML。
  • XPath predicate [position() ge (last()-1)]给出了最后两个标记。
    • SQL语言**
-- DDL and sample data population, start
DECLARE @tbl TABLE (tokens VARCHAR(256));
INSERT @tbl VALUES
('123_456_ABC_DEF'),
('12_34_456_XYZ_PQR'),
('LMN_OPQ_123_456');
-- DDL and sample data population, end

DECLARE @separator CHAR(1) = '_';

SELECT t.*
    , REPLACE(c.query('data(/root/r[position() ge (last()-1)])').value('.', 'VARCHAR(256)')
        , SPACE(1), @separator) AS Result
FROM @tbl AS t
CROSS APPLY (SELECT TRY_CAST('<root><r><![CDATA[' + 
      REPLACE(tokens, @separator, ']]></r><r><![CDATA[') + 
      ']]></r></root>' AS XML)) AS t1(c);
    • 产出**

| 代币|结果|
| - ------|- ------|
| 123_456_ABC_定义|ABC_定义|
| 12_34_456_XYZ_生产工艺评定报告|XYZ_PQR|
| LMN_OPQ_123_456|123 - 456|

bq8i3lrv

bq8i3lrv3#

这是使用JSON和CROSS APPLY的另一种选择

    • 示例**
Select NewValue = reverse(JSON_VALUE(JS,'$[0]')+'_'+JSON_VALUE(JS,'$[1]'))
 From  YourTable A
 Cross Apply (values ('["'+replace(string_escape(reverse([Field Name]),'json'),'_','","')+'"]') ) B(JS)
    • 结果**
NewValue
ABC_DEF
XYZ_PQR
123_456

相关问题