2

我使用从 SSRS 导入信息的存储过程更新表。我有一个称为页面的字段。页面字段可以包含以下三种格式之一:

  1. 纯数字字段,例如 1,2 3 等。
  2. 数字和字母组合,例如 1D、4C、7Z 等。
  3. 一个数字、一个破折号和两个附加数字,例如 2-01、3-04、1-09 等

我需要为每种格式创建一个页面等效项以进行排序以及帮助定义页码的一般类别。示例 1 是基本页面,示例 2 是艺术页面,示例 3 是文本页面。

对于等价,示例 1 将产生 1.00 格式。示例 2 将根据字母的数字等效值得出 1.01 到 1.26 的等效值。最后,示例 3 将导致 1.26 加上 .01 * 破折号右侧的值。最小值为 1.27。

我已经在 Excel 中完成了此操作,但似乎无法在 SQL 中正确编写公式。

我正在使用 SQL Server 2008 R2

4

3 回答 3

1

这似乎涵盖了您描述的情况:

declare @t table (val varchar(10))
insert into @t 
select '1' union select '2' union
select '1D' union select '4S' union
select '2-01' union select '1-09'

select val, case
    when val not like '%[^0-9]%' then val + '.00'
    when val like '[0-9][A-Z]' then '1.' + right('0' + convert(varchar, ascii(right(val, 1))-64), 2)
    when val like '%-%' then convert(varchar, 1.26 + (0.01 * cast(substring(val, charindex('-', val)+1, 2) as int)))
    else val end
from
    @t

TSQL 不是用于字符串操作和解析的出色语言,因此您可能需要考虑为此使用 CLR 函数或存储过程。并且应用这些规则是单元测试的一个很好的候选,因为定义和使用输入和输出值的测试集来验证你的代码很简单。

于 2013-01-18T17:32:12.763 回答
1

这是另一种选择。

尽管此答案基于Pondlife's,但它返回decimal结果而不是字符串。

它大量使用隐式转换,这就是它看起来更紧凑的原因。

它还假设仅使用您的问题中提到的三种格式。如果有一个“无效”格式的值,它将破坏这个解决方案。

SELECT
  CASE
    WHEN PageNo NOT LIKE '%[^0-9]%' THEN PageNo
    WHEN PageNo     LIKE '%[A-Z]'   THEN LEFT(PageNo, LEN(PageNo) - 1)
                                         + (ASCII(RIGHT(PageNo, 1)) - 64) * 0.01
    WHEN PageNo     LIKE '%-%'      THEN REPLACE(PageNo, '-', '.') * 1.0 + 0.26
  END
FROM ...
于 2013-01-21T09:11:55.633 回答
0

这很丑陋,可能性能不是很好,但是:

select
  page_num,
  case
    when page_num like '%A' then substring(page_num, 1, len(page_num)-1) + '.01'
    when page_num like '%B' then substring(page_num, 1, len(page_num)-1) + '.02'
    when page_num like '%C' then substring(page_num, 1, len(page_num)-1) + '.03'
    when page_num like '%D' then substring(page_num, 1, len(page_num)-1) + '.04'
    when page_num like '%E' then substring(page_num, 1, len(page_num)-1) + '.05'
    when page_num like '%F' then substring(page_num, 1, len(page_num)-1) + '.06'
    when page_num like '%G' then substring(page_num, 1, len(page_num)-1) + '.07'
    when page_num like '%H' then substring(page_num, 1, len(page_num)-1) + '.08'
    when page_num like '%I' then substring(page_num, 1, len(page_num)-1) + '.09'
    when page_num like '%J' then substring(page_num, 1, len(page_num)-1) + '.10'
    when page_num like '%K' then substring(page_num, 1, len(page_num)-1) + '.11'
    when page_num like '%L' then substring(page_num, 1, len(page_num)-1) + '.12'
    when page_num like '%M' then substring(page_num, 1, len(page_num)-1) + '.13'
    when page_num like '%N' then substring(page_num, 1, len(page_num)-1) + '.14'
    when page_num like '%O' then substring(page_num, 1, len(page_num)-1) + '.15'
    when page_num like '%P' then substring(page_num, 1, len(page_num)-1) + '.16'
    when page_num like '%Q' then substring(page_num, 1, len(page_num)-1) + '.17'
    when page_num like '%R' then substring(page_num, 1, len(page_num)-1) + '.18'
    when page_num like '%S' then substring(page_num, 1, len(page_num)-1) + '.19'
    when page_num like '%T' then substring(page_num, 1, len(page_num)-1) + '.20'
    when page_num like '%U' then substring(page_num, 1, len(page_num)-1) + '.21'
    when page_num like '%V' then substring(page_num, 1, len(page_num)-1) + '.22'
    when page_num like '%W' then substring(page_num, 1, len(page_num)-1) + '.23'
    when page_num like '%X' then substring(page_num, 1, len(page_num)-1) + '.24'
    when page_num like '%Y' then substring(page_num, 1, len(page_num)-1) + '.25'
    when page_num like '%Z' then substring(page_num, 1, len(page_num)-1) + '.26'
    when page_num like '%-%' then 
      substring(page_num, 1, charindex('-', page_num)-1) + '.' + 
      cast((26+cast(substring(page_num, charindex('-', page_num)+1, len(page_num)) as int)) as varchar(12))                                                                                                          
    else page_num + '.00'
  end
from pages

有关我正在测试的完整架构,请参阅SQL Fiddle 。

也就是说,我强烈建议将您的架构更新为包含规范化页码的内容,并在将其转换为表格的过程中。

于 2013-01-18T16:50:33.543 回答