【问题标题】:Get Number from string using SUBSTRING() SQL Server 2008-R2使用 SUBSTRING() SQL Server 2008-R2 从字符串中获取数字
【发布时间】:2014-01-27 03:02:34
【问题描述】:

我有一些如下所示的数据:

AS WRITTEN                                             | UNITS | ROUTINE
TRANSFUSE - RED BLOOD CELLS 1 UNITS ROUTINE, TRANSF... | 1     | 
TRANSFUSE - RED BLOOD CELLS 2UNITS ROUTINE, TRAN...    | 2     |
TRANSFUSE FRESH FROZEN PLASMA 2 ROUTINE                |       | 2
TRANSFUSE - RED BLOOD CELLS 2 UNITS ROUTINE, TRAN...   | 2     |
TRANSFUSE CRYOPRECIPITATE 10 ROUTINE                   |       |    <- 10 SHOULD BE HERE

我正在使用以下SELECT 语句来获取值,这可能是一种粗略的做法,但这是我第一次涉足SUBSTRING() CHARINDEX ETC。

SELECT 语句:

, CASE
    WHEN SUBSTRING(SO.DESC_AS_WRITTEN, CHARINDEX('UNIT', SO.DESC_AS_WRITTEN)-2,1) NOT IN (
        '1','2','3','4','5','6','7','8','9','10','11'
    )
        THEN ''
    ELSE SUBSTRING(SO.DESC_AS_WRITTEN, CHARINDEX('UNIT', SO.DESC_AS_WRITTEN)-2,1)
  END AS [UNITS]
, CASE 
    WHEN SUBSTRING(SO.DESC_AS_WRITTEN, CHARINDEX('ROUTINE', SO.DESC_AS_WRITTEN)-2,1) NOT IN (
        '1','2','3','4','5','6','7','8','9','10','11'
    )
        THEN ''
    ELSE SUBSTRING(SO.DESC_AS_WRITTEN, CHARINDEX('ROUTINE', SO.DESC_AS_WRITTEN)-2,2)
  END AS [ROUTINE]

如上所述,10 应该显示在ROUTINE 下的最后一列中,但不是,我不明白为什么。所有其他人似乎都工作得很好。

谢谢,

更新 在@EkriirkE 和@GoatCO 的大力帮助下,我使用了以下代码作为解决方案:

,(CAST
    (ISNULL
        (REPLACE
            (REPLACE
                (REPLACE
                    (CASE 
                        WHEN PATINDEX('%[0-9]UNIT%',so.desc_as_written) > 0 
                            THEN SUBSTRING(so.desc_as_written,
                                 PATINDEX('%[0-9]UNIT%',so.desc_as_written)-1,2) 
                        WHEN PATINDEX('%[0-9] UNIT%',so.desc_as_written) > 0 
                            THEN SUBSTRING(so.desc_as_written,
                                 PATINDEX('%[0-9] UNIT%',so.desc_as_written)-1,2)
                        WHEN PATINDEX('%[0-9]ROUTINE%',so.desc_as_written) > 0 
                            THEN SUBSTRING(so.desc_as_written,
                                 PATINDEX('%[0-9]ROUTINE%',so.desc_as_written)-1,2)
                        WHEN PATINDEX('%[0-9] ROUTINE%',so.desc_as_written) > 0 
                            THEN SUBSTRING(so.desc_as_written,
                                 PATINDEX('%[0-9] ROUTINE%',so.desc_as_written)-1,2)
                        WHEN PATINDEX('%[0-9]STAT%',so.desc_as_written) > 0 
                            THEN SUBSTRING(so.desc_as_written,
                                 PATINDEX('%[0-9]STAT%',so.desc_as_written)-1,2)
                        WHEN PATINDEX('%[0-9] STAT%',so.desc_as_written) > 0 
                            THEN SUBSTRING(so.desc_as_written,
                                 PATINDEX('%[0-9] STAT%',so.desc_as_written)-1,2)
                        WHEN PATINDEX('%[0-9]TODAY%',so.desc_as_written) > 0 
                            THEN SUBSTRING(so.desc_as_written,
                                 PATINDEX('%[0-9]TODAY%',so.desc_as_written)-1,2)
                        WHEN PATINDEX('%[0-9] TODAY%',so.desc_as_written) > 0 
                            THEN SUBSTRING(so.desc_as_written,
                                 PATINDEX('%[0-9] TODAY%',so.desc_as_written)-1,2) 
                    END,
                'S',''),
            'T',''),
        'U','')
    , 0)
AS INT)
) AS [TEST]

【问题讨论】:

    标签: sql sql-server-2008 substring


    【解决方案1】:

    从查找 UNIT 或 ROUTINE 备份 2 个字符后,您只需要 1 个字符。 “10 ROUTINE”返回不在您的 IN 列表中的“0”。即您的代码仅适用于个位数。您应该取 -3 个字符然后 2 个字符长度并修剪空格,但如果您的样本中确实有“2UNITS”与“2 UNITS”之类的运行,那么您会遇到更多困难

    【讨论】:

    • 非常感谢,这确实奏效了,我不必担心那些尚未发生的事情,但这是一个好点,我需要考虑一下。
    • @MCP_infiltrator 你在你的例子中有这样的磨合2UNITS
    • @Goat CO 这就是我提出它的原因...欢迎!
    【解决方案2】:

    这可能更可取:

    SELECT *,CASE WHEN PATINDEX('%[0-9]UNITS%',written) > 0 THEN SUBSTRING(written,PATINDEX('%[0-9]UNITS%',written)-1,2) 
                  WHEN PATINDEX('%[0-9] UNITS%',written) > 0 THEN SUBSTRING(written,PATINDEX('%[0-9] UNITS%',written)-1,2) 
             END
            ,CASE WHEN PATINDEX('%[0-9]ROUTINE%',written) > 0 THEN SUBSTRING(written,PATINDEX('%[0-9]ROUTINE%',written)-1,2)
                  WHEN PATINDEX('%[0-9] ROUTINE%',written) > 0 THEN SUBSTRING(written,PATINDEX('%[0-9] ROUTINE%',written)-1,2)
             END 
    FROM  #Table1
    

    演示:SQL Fiddle

    CASE 语句包装在替换中可能比处理给定变体获取适当数量的字符更简单,即:

    SELECT *,REPLACE(CASE WHEN PATINDEX('%[0-9]UNITS%',written) > 0 THEN SUBSTRING(written,PATINDEX('%[0-9]UNITS%',written)-1,2) 
                          WHEN PATINDEX('%[0-9] UNITS%',written) > 0 THEN SUBSTRING(written,PATINDEX('%[0-9] UNITS%',written)-1,2) 
                     END,'S','')                       
            ,REPLACE(CASE WHEN PATINDEX('%[0-9]ROUTINE%',written) > 0 THEN SUBSTRING(written,PATINDEX('%[0-9]ROUTINE%',written)-1,2)
                          WHEN PATINDEX('%[0-9] ROUTINE%',written) > 0 THEN SUBSTRING(written,PATINDEX('%[0-9] ROUTINE%',written)-1,2)
                     END,'S','') 
    FROM  #Table1
    

    【讨论】:

    • 谢谢你,我必须尝试一下,因为我收到以下错误conversion failed when converting the varchar value 's1' to data type int.
    • @MCP_infiltrator 可能是您遇到没有空间的情况,例如 CELLS1 将这些空间包装在 REPLACE() 语句中可能是解决此问题的最简单方法。
    • 我必须在REPLACE() 上做一些阅读,因为您的回答是我第一次遇到它。感谢您的帮助
    • @MCP_infiltrator 添加了替换回答,如果您有多个字符要替换,它们可以嵌套,即:REPLACE(REPLACE(CASE ... END, 'S',''),'U','') 将替换 CASE 中返回的任何 SU没有任何内容的声明''.
    • 我选择将此答案作为已接受的答案,你们俩都帮了我很多,我只是觉得这是一个更可靠的答案,同时它还向我介绍了一些新功能。跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多