【问题标题】:Use Replace function with conditions使用带条件的替换功能
【发布时间】:2014-04-04 08:25:09
【问题描述】:

我是 SQL 新手。我有一个 sql 查询

select replace('P' + ltrim(rtrim(upper(columnvalue))),'PP','P') from tablename

这里我将列值设为P0987799, R0987884, 9745456 OR RT087477(例如)

现在我想从该查询中获取单一格式的值(从 p 开始,然后是数字)。好像该值以p (P0987799) 开头,那么没问题。

但 value 以 RRT 开头,则应替换为 P

如何做到这一点?

【问题讨论】:

  • 列值有固定长度吗?
  • Noo .. 列值长度不固定

标签: sql sql-server-2008 sql-server-2005 replace


【解决方案1】:

这里有一个想法......

DECLARE @your_table table (
   columnvalue varchar(50)
);

INSERT INTO @your_table (columnvalue)
  VALUES ('P0987799')
       , ('R0987884')
       , ('9745456')
       , ('RT087477')
;

-- Verbose version (shows individual steps)
SELECT columnvalue
     , start_of_numbers
     , numeric_part
     , 'P' + numeric_part As prefixed_with_p
FROM   (
        SELECT columnvalue
             , start_of_numbers
             , SubString(columnvalue, start_of_numbers, 50) As numeric_part --50 = length of field (varchar(50))
        FROM   (
                SELECT columnvalue
                     , PatIndex('%[0-9]%', columnvalue) As start_of_numbers -- find the first number
                FROM   @your_table
               ) As x
       ) As y
;

-- Shortened version
SELECT columnvalue
     , 'P' + SubString(columnvalue, PatIndex('%[0-9]%', columnvalue), 50) As prefixed_with_p
FROM   @your_table
;

首先找到第一个数字字符的位置,然后去掉该点之前的所有内容(只留下数字)。然后在开头贴一个“P”!

结果:

columnvalue  start_of_numbers  numeric_part  prefixed_with_p
------------ ----------------- ------------- ----------------
P0987799     2                 0987799       P0987799
R0987884     2                 0987884       P0987884
9745456      1                 9745456       P9745456
RT087477     3                 087477        P087477


columnvalue  prefixed_with_p
------------ ----------------
P0987799     P0987799
R0987884     P0987884
9745456      P9745456
RT087477     P087477

编辑:如果您想缩小前缀范围:

SELECT columnvalue
     , start_of_numbers
     , numeric_part
     , alpha_part
     , CASE WHEN alpha_part IN ('P', 'R', 'RT') THEN -- limit the prefixing
         'P' + numeric_part
       ELSE
         numeric_part
       END As prefixed_with_p
FROM   (
        SELECT columnvalue
             , start_of_numbers
             , SubString(columnvalue, start_of_numbers, 50) As numeric_part --50 = length of field (varchar(50))
             , SubString(columnvalue, 0, start_of_numbers) As alpha_part
        FROM   (
                SELECT columnvalue
                     , PatIndex('%[0-9]%', columnvalue) As start_of_numbers
                FROM   @your_table
               ) As x
       ) As y
;

结果:

columnvalue  start_of_numbers  numeric_part  alpha_part  prefixed_with_p
------------ ----------------- ------------- ----------- ----------------
P0987799     2                 0987799       P           P0987799
R0987884     2                 0987884       R           P0987884
9745456      1                 9745456                   9745456
RT087477     3                 087477        RT          P087477

【讨论】:

  • 'P' + right(c, len(c) + 1- PatIndex('%[0-9]%', c)) As prefixed_with_p 避免50
  • @rudym 虽然这会起作用,但它需要一个额外的函数调用。对于这种任务,我经常“懒惰”并输入 8000(标准 varchar 字段的最大长度)。当我不那么懒惰时,即代码正在投入生产 - 然后我会查找实际的字段长度。
【解决方案2】:

请查找以下查询

 DECLARE @your_table table (
   columnvalue varchar(50)
);

INSERT INTO @your_table (columnvalue)
  VALUES ('P0987799')
       , ('R0987884')
       , ('9745456')
       , ('RT087477')



select CASE WHEN (ColumnValue like 'R%' OR ColumnValue like 'P%'  ) THEN 'P' eLSE '' END +
SUBSTRING(ColumnValue,PATINDEX('%[0-9]%',ColumnValue),LEN(ColumnValue)-(PATINDEX('%[0-9]%',ColumnValue))+1) as FinalValue
from @your_table

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-25
    • 2017-02-01
    • 2015-04-12
    • 1970-01-01
    • 2013-07-17
    • 2015-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多