SET @sql =  "SELECT *
            FROM   TABLE
            WHERE  test = (expression FOR CASE 1 resulting IN INT 1)
                   AND result = (expression FOR CASE 2 resulting IN INT 1)"
    
sql
sql-server
sql-server-2008
tsql
parsing
Rodricks
Rodricks
发布于 2013-02-05
4 个回答
gRUNGEbOB
gRUNGEbOB
发布于 2013-02-05
0 人赞同

看起来你已经有了一个满足你需求的解决方案,但我有一个小技巧,我用来从字符串中提取数字,我想这可能会让别人受益。它利用了FOR XML语句的优势,避免了显式循环。它是一个很好的内联表函数或简单的标量。随你怎么做吧 :)

DECLARE @String varchar(255) = 'This1 Is2 my3 Test4 For Number5 Extr@ct10n';
SELECT
    CAST(( 
        SELECT CASE --// skips alpha. make sure comparison is done on upper case
            WHEN ( ASCII(UPPER(SUBSTRING(@String, Number, 1))) BETWEEN 48 AND 57 )
            THEN SUBSTRING(@String, Number, 1)
            ELSE ''END
            SELECT TOP 255 --// east way to get a list of numbers
                                           --// change value as needed.
                ROW_NUMBER() OVER ( ORDER BY ( SELECT 1 ) ) AS Number
             FROM master.sys.all_columns a
                CROSS JOIN master.sys.all_columns b 
        ) AS n
        WHERE Number <= LEN(@String)
        --// use xml path to pivot the results to a row
        FOR XML PATH('') ) AS varchar(255)) AS Result

结果 ==> 1234510

John
我需要花点时间来弄清楚这到底是如何工作的,但它今晚帮助了我,我很感谢它!我很高兴。谢谢。
Imtiyaz
Imtiyaz
发布于 2013-02-05
0 人赞同

你可以编写一个sql函数,它可以通过你的搜索查询来使用。 下面是示例代码。

CREATE FUNCTION udf_extractInteger(@string VARCHAR(2000))
RETURNS VARCHAR(2000)
    BEGIN
        DECLARE @count int
        DECLARE @intNumbers VARCHAR(1000)
        SET @count = 0
        SET @intNumbers = ''
        WHILE @count <= LEN(@string)
        BEGIN 
            IF SUBSTRING(@string, @count, 1)>='0' and SUBSTRING (@string, @count, 1) <='9'
                BEGIN
                    SET @intNumbers = @intNumbers + SUBSTRING (@string, @count, 1)
            SET @count = @count + 1
        RETURN @intNumbers
SELECT dbo.udf_extractInteger('hello 123 world456') As output

OUTPUT: 123456

引用自 :http://www.ittutorials.in/source/sql/sql-function-to-extract-only-numbers-from-string.aspx

Tim Lehner
Tim Lehner
发布于 2013-02-05
已采纳
0 人赞同

由于你有稳定的文本和只有两个元素,你可以很好地利用替换Parsename

declare @string varchar(100) = 'TEST RESULTS\TEST 1\RESULT 2'
select cast(parsename(replace(replace(@string, 'TEST RESULTS\TEST ', ''), '\RESULT ', '.'), 2) as int) as Test
    , cast(parsename(replace(replace(@string, 'TEST RESULTS\TEST ', ''), '\RESULT ', '.'), 1) as int) as Result
       Test      Result
----------- -----------
          1           2

替换部分确实假定文本和间距始终相同,并为Parsename设置了句号。

谢谢蒂姆,能够得到预期的结果。
sgeddes
sgeddes
发布于 2013-02-05
0 人赞同

该方法使用SUBSTRING,PARSENAME, 和PATINDEX

SELECT 
  SUBSTRING(PARSENAME(c,2), PATINDEX('%[0-9]%',PARSENAME(c,2)), LEN(c)) Test,
  SUBSTRING(PARSENAME(c,1), PATINDEX('%[0-9]%',PARSENAME(c,1)), LEN(c)) Result
FROM (   SELECT REPLACE(@val, '\', '.') c) t

使用PARSENAME 来分割字符串。 字符串的文本并不重要 -- 它只需要包含2个反斜线就可以解析为3个元素。 使用PATINDEX 和正则表达式来替换结果中的非数字值。 如果数字前面的文本曾经包含数字,这就需要进行调整。