【问题标题】:How to count string between string in sql如何在sql中的字符串之间计算字符串
【发布时间】:2016-11-13 06:05:44
【问题描述】:

我有一个具有不同长度值的数据。

例如我有 2 行数据:

 CL-CI/PST/102/VII/2016
 CL-CI/PST/0102/VII/2016

它们的区别是102(3位)和0102(4位)

我想在我的 SQL 检查中:

if (3Digits)
begin
    ....
end
else
begin
    ....
end

记录的数据格式不固定。只是没有固定在这个字符串 VII/2016 上(基于罗马数字/年的月份)。

我知道如何使用 LEN 计算字符串。但我的问题是当我选择前 1 个数据时。在我获得的前 1 位数据中,我想动态检查我从前 1 位获得的数据是否为 ​​4 位/3 位。我被困住了。

【问题讨论】:

  • 这是固定格式还是数据格式可能因记录而异?
  • 对于这个字符串 VII/2016(基于月份(罗马数字)/年份)不固定
  • 固定不是字符数,固定是你的字符串在第二个/和第三个/之间,就像这篇文章中的stackoverflow.com/questions/17975150/…
  • if 3digits 块中发生了什么,它是如此具体,足以与所有其他场景分开?添加前导零?
  • 我想做序列号,但这取决于我得到的最后一条记录。例如我得到了 CL-CI/PST/102/VII/2016,所以下一个新的序列号是 CL-CI/PST/0103/VII/2016。例如,当我再次选择前 1 名时,我得到了 CL-CI/SPG/069/VII/2016,因此下一个序列号必须为 CL-CI/SPG/0068/VII/2016。 3 位数据是生产中的旧格式版本。我必须更改为 4 位数格式。此格式编号是每个分支的。这就是为什么我想检查使用 if 条件。但是任何想法都会受到欢迎,

标签: sql sql-server


【解决方案1】:

这样试试

简单:只是长度

DECLARE @s VARCHAR(100)='CL-CI/PST/0102/VII/2016';
SELECT LEN(CAST('<x>' + REPLACE(@s,'/','</x><x>')+'</x>' AS XML).value('/x[3]','varchar(max)'))

结果是 4

基于集合的方法

DECLARE @tbl TABLE(ID INT IDENTITY,YourString VARCHAR(100),OtherValue VARCHAR(100));
INSERT INTO @tbl(YourString,OtherValue) VALUES
 ('CL-CI/PST/102/VII/2016','With 3 digits')
,('CL-CI/PST/0102/VII/2016','With 4 digits');

WITH ExtendByPart3 AS
(
    SELECT *
          ,CAST('<x>' + REPLACE(YourString,'/','</x><x>')+'</x>' AS XML).value('/x[3]','varchar(max)') AS Part3
    FROM @tbl
)
SELECT *,LEN(Part3) AS LenPart3 FROM ExtendByPart3

结果

ID  YourString              OtherValue      Part3   LenPart3
1   CL-CI/PST/102/VII/2016  With 3 digits   102     3
2   CL-CI/PST/0102/VII/2016 With 4 digits   0102    4

顺便说一句:有几个问题:如何访问分隔字符串的 X 项,大多数答案都带有非常复杂的 CTE、循环、CLR 方法...这种方法是直接的,安全输入。将.value() 函数的nvarchar(max) 更改为int,如果需要,您将获得该数字。

I placed an answer to one of these questions myself,但是 - 由于这个问题已经存在多年 - 主要答案非常过时并且 - IMO - 过时了。但仍然值得一读……

检索所有值

如果您也可能对您的其他价值观感兴趣,您可以这样做:

DECLARE @tbl TABLE(ID INT IDENTITY,YourString VARCHAR(100),OtherValue VARCHAR(100));
INSERT INTO @tbl(YourString,OtherValue) VALUES
 ('CL-CI/PST/102/VII/2016','With 3 digits')
,('CL-CI/PST/0102/VII/2016','With 4 digits');

WITH Splitted AS
(
    SELECT CAST('<x>' + REPLACE(YourString,'/','</x><x>')+'</x>' AS XML) AS XMLData
    FROM @tbl
)
SELECT XMLData.value('/x[1]','varchar(max)') AS Part1
      ,XMLData.value('/x[2]','varchar(max)') AS Part2
      ,XMLData.value('/x[3]','int') AS Number
      ,XMLData.value('/x[4]','varchar(max)') AS MonthRoman
      ,XMLData.value('/x[5]','int') AS TheYear
FROM Splitted

结果(注意:返回为int的数字没有前导零)

Part1   Part2   Number  MonthRoman  TheYear
CL-CI   PST     102     VII         2016
CL-CI   PST     102     VII         2016

【讨论】:

    【解决方案2】:

    也许caselike 就足够了:

    select (case when col like '%/%/[0-9][0-9][0-9]/%' then <3 digit stuff>
                 when col like '%/%/[0-9][0-9][0-9][0-9]/%' then <4 digit stuff>
            end)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-14
      • 1970-01-01
      • 2022-12-21
      相关资源
      最近更新 更多