【问题标题】:What is the best way to convert this to SQL将其转换为 SQL 的最佳方法是什么
【发布时间】:2014-07-25 16:18:05
【问题描述】:

我知道对于这里的数据库大师来说,这应该是轻而易举的事。我的数据库中有一个字段,格式为' A/B/C/D/E/F '

格式无关紧要,我通常需要最后两部分,所以对于上面的内容,

'EF'

但如果我有另一个字符串

AB/CD/EF/GH == EFGH

我希望让最后两部分像这样“EFGH”返回

有谁知道我可以做的一个 SQL 函数来拆分它

我正在使用 Microsoft SQL Server 2012 - 我希望这会有所帮助,

这里是 C# 代码。

var myText = "A/B/C/D/E/F";
var identificationArray = myText.Split('/');

if(identificationArray.Length >= 2)
{
    var friendlyId = identificationArray[identificationArray.Length - 2] + identificationArray[identificationArray.Length - 1];

    return friendlyId;
}
return "";

【问题讨论】:

  • 这可能与您使用的平台 (DBMS) 非常相关。你能用这个平台更新你的问题吗?在这种情况下,数据库、.net 和优化标签似乎是多余的。
  • 你的格式是A/B/C/D/E/F还是AB/CD/EF/GH?你有一个例子。
  • 加 1 用于使用 doddle 这个词。
  • 这不是浪费,这是一个完全有效的问题。我不确定答案是什么,但我确实找到了您可以参考的this post
  • 别害羞。这是提问的地方。看看我引用的问题,当您能够解决问题时,请随时回答您自己的问题并与其他人分享您的知识。总有一天,有人会遇到同样的问题,并且可能会在此处提出您的问题以寻求解决方案。

标签: c# sql .net database sql-server-2012


【解决方案1】:

这是一个答案,它以相反的顺序在字符串中搜索第二个正斜杠并返回删除了正斜杠的子字符串:

declare @s varchar(20)
set @s = 'A/B/C/D/E/F'

-- result: 'EF'
select reverse(replace(left(reverse(@s), charindex('/', reverse(@s), charindex('/', reverse(@s)) + 1)), '/', ''))

set @s = 'AB/CD/EF/GH'

-- result: 'EFGH'
select reverse(replace(left(reverse(@s), charindex('/', reverse(@s), charindex('/', reverse(@s)) + 1)), '/', ''))

使用其他几个输入对此进行测试:

set @s = '/AB/CD' -- result: 'ABCD'
set @s = 'AB/CD'  -- result: an empty string '' -- you may not want this result
set @s = 'AB'     -- result: an empty string ''

这是用一系列公用表表达式 (CTE) 做同样事情的一种非常复杂的方法。感谢 Itzik Ben-Gan 使用 CTE 技术使用交叉连接生成一个计数表:

declare @s varchar(50)
set @s = 'A/B/C/D/E/F/G'
--set @s = 'AB/CD/EF/GH'
--set @s = 'AB/CD'
--set @s = 'ABCD/EFGH/IJKL'
--set @s = 'A/B'
-- set @s = 'A'

declare @result varchar(50)
set @result = ''

;with
-- cross-join a meaningless set of data together to create a lot of rows
Nbrs_2    (n) AS (SELECT 1 UNION SELECT 0 ),
Nbrs_4    (n) AS (SELECT 1 FROM Nbrs_2     n1 CROSS JOIN Nbrs_2     n2),
Nbrs_16   (n) AS (SELECT 1 FROM Nbrs_4     n1 CROSS JOIN Nbrs_4     n2),
Nbrs_256  (n) AS (SELECT 1 FROM Nbrs_16    n1 CROSS JOIN Nbrs_16    n2),
Nbrs_65536(n) AS (SELECT 1 FROM Nbrs_256   n1 CROSS JOIN Nbrs_256   n2),
Nbrs      (n) AS (SELECT 1 FROM Nbrs_65536 n1 CROSS JOIN Nbrs_65536 n2),
-- build a table of numbers from the data above; this is insanely fast
nums(n) as
(
   select row_number() over(order by n) from Nbrs
),
-- split the string into separate rows per letter
letters(n, c) as
(
    select n, substring(@s, n, 1)
    from nums
    where n < len(@s) + 1
),
-- count the slashes from the rows in descending order
-- the important slash is the second one from the end
slashes(n, num) as
(
    select n, ROW_NUMBER() over (order by n desc)
    from letters
    where c = '/'
)
select @result = @result + c
from letters
where n > (select n from slashes where num = 2) -- get everything after the second slash
and c <> '/' -- and drop out the other slash

select @result

【讨论】:

  • 很好,我喜欢你在没有案例陈述的情况下如何做到这一点
  • @Aducci 谢谢。我不确定所有案例都完全符合 OP 的要求,但它很接近。我们提出了非常相似的解决方案!
【解决方案2】:

您需要反转字符串并找到/ 字符的第二次出现。一旦你有了它,它就很简单了,只需要大量的函数调用来获得所需的格式

declare @test varchar(max);
set @test = 'b/b/a/v/d';

select 
    case
        when charindex('/', reverse(@test), charindex('/', reverse(@test))+1) = 0 then ''
        else replace(reverse(substring(reverse(@test), 0, charindex('/', reverse(@test), charindex('/', reverse(@test))+1))), '/', '')
    end

【讨论】:

    【解决方案3】:

    我了解您想在 SQL 中执行此操作。但是您是否考虑过使用 SQL CLR 用户定义函数?它将比 SQL 执行得更快。无论如何,你的逻辑是用 C# 实现的,这绝对比 SQL 中的逻辑简单。

    【讨论】:

      【解决方案4】:

      聚会迟到了,但这是我的尝试:

      declare @text varchar(max), @reversedtext varchar(max)
      
      select @text = 'AB/CD/EF/GH'
      select @reversedtext = reverse(@text)
      
      declare @pos1 int
      declare @pos2 int
      declare @pos3 int
      
      
      select @pos1 = charindex('/', @reversedtext)
      select @pos2 = charindex('/', replace(@reversedtext, left(@reversedtext, @pos1), ''))
      select @pos3 = @pos1 + @pos2
      
      select REPLACE(RIGHT(@text, @pos3), '/', '')
      

      【讨论】:

        猜你喜欢
        • 2016-05-29
        • 2012-02-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多