Sql server TSQL中的正则表达式

Sql server TSQL中的正则表达式,sql-server,tsql,sql-server-2005,Sql Server,Tsql,Sql Server 2005,在e_vis_name列的单元格中,我有一个组织结构,其中以\符号划分的分区,例如 莫斯科\方向 雅罗斯拉夫尔\销售 Omsk\商业中心\销售 我需要在first\symbol之后剪切所有内容,以获得以下结果: 莫斯科 雅罗斯拉夫尔 鄂木斯克 我该怎么做呢?您可以使用和的组合,如下所示: SELECT LEFT(colname, CHARINDEX('\', colname)-1) FROM table 编辑:在没有\符号的情况下,如果只想获取整个列,可以执行以下操作: SELECT

在e_vis_name列的单元格中,我有一个组织结构,其中以\符号划分的分区,例如

莫斯科\方向 雅罗斯拉夫尔\销售 Omsk\商业中心\销售 我需要在first\symbol之后剪切所有内容,以获得以下结果:

莫斯科 雅罗斯拉夫尔 鄂木斯克
我该怎么做呢?

您可以使用和的组合,如下所示:

SELECT LEFT(colname, CHARINDEX('\', colname)-1) FROM table
编辑:在没有\符号的情况下,如果只想获取整个列,可以执行以下操作:

SELECT 
    CASE WHEN CHARINDEX('\', colname) > 0 THEN LEFT(colname, CHARINDEX('\', colname)-1)
    ELSE ISNULL(colname, '') 
    END
FROM table
也就是说,如果有一个\,那么将字符带到该点,否则将带整个列。如果列为NULL,则只需设置一个空字符串


我相信你可以根据自己的目的来调整它。

在下面的几个例子中,你可以选择许多方法来实现你的需要

--------------------------------------------------------------------------------
-- TEMP TABLE WITH DATA SAMPLE
DECLARE @table AS TABLE ( Division VARCHAR(100) )

INSERT INTO @table ( Division                       )
VALUES             ( 'Moscow\Direction'             )
,                  ( 'Yaroslavl\Sales'              )
,                  ( 'Omsk\Commercial center\Sales' )
,                  ( 'Voronezh'                     )

--------------------------------------------------------------------------------
-- variant using PARSENAME
SELECT REVERSE(PARSENAME(REVERSE(REPLACE(Division, '\', '.')), 1)) AS Town
FROM @table AS T

-------------------------------------------------------------------------------
-- variant using SUBSTRING AND CHARINDEX
SELECT  SUBSTRING(division, 1,
                  CASE WHEN CHARINDEX('\', division) = 0 THEN LEN(Division)
                       ELSE CHARINDEX('\', division) - 1
                  END) AS Town
FROM    @table AS T

--------------------------------------------------------------------------------
-- variant using SUBSTRING AND PATINDEX
SELECT  SUBSTRING(division, 1,
                  CASE WHEN PATINDEX('%\%', division) = 0 THEN LEN(Division)
                       ELSE PATINDEX('%\%', division) - 1
                  END) AS Town
FROM    @table AS T

--------------------------------------------------------------------------------
-- variant using LEFT AND PATINDEX

SELECT  LEFT(division,
             CASE WHEN PATINDEX('%\%', division) = 0 THEN LEN(Division)
                  ELSE PATINDEX('%\%', division) - 1
             END) AS Town
FROM    @table AS T

--------------------------------------------------------------------------------
-- variant using LEFT AND CHARINDEX
SELECT  LEFT(division,
             CASE WHEN CHARINDEX('\', division) = 0 THEN LEN(Division)
                  ELSE CHARINDEX('\', division) - 1
             END) AS Town
FROM    @table AS T

--------------------------------------------------------------------------------
-- variant using recursive cte, substring, top with ties by Row_number()
;
WITH tally
AS (SELECT n = 1
    UNION ALL
    SELECT n = n + 1
    FROM tally
    WHERE n < 100)

SELECT TOP 1 WITH TIES SUBSTRING(A.Division,1,B.n-1) AS Town
FROM @table AS A
JOIN tally  AS B ON SUBSTRING(A.Division + '\', B.n , 1)= '\'
ORDER BY ROW_NUMBER() OVER (PARTITION BY A.Division ORDER BY B.n)

--------------------------------------------------------------------------------
-- variant using recursive cte, substring, row_number, subquery
;
WITH tally
AS (SELECT n = 1
    UNION ALL
    SELECT n = n + 1
    FROM tally
    WHERE n < 100)

SELECT T.TOWN
FROM (SELECT SUBSTRING(A.Division,1,B.n-1) AS TOWN,
             ROW_NUMBER() OVER (PARTITION BY A.Division ORDER BY B.n) AS RN
      FROM @table AS A JOIN tally  AS B ON SUBSTRING(A.Division + '\', B.n , 1)= '\'
      ) AS T
WHERE RN = 1
作为一些备选方案:

使用左键:

使用子字符串:

使用素材:

使用PARSENAME:


Msg 537,第16级,状态2,第1行传递给LEFT或SUBSTRING函数的长度参数无效。有一些分区没有“\”符号,例如,由于该列中缺少\而导致错误的“JSC”。我加了一张支票,在没有\的情况下返回整列。这张支票适合我,非常感谢你的帮助变量使用子字符串和CHARINDEX选择子字符串division,1,CASE当CHARINDEX'\',division=0,然后LENDivision ELSE CHARINDEX'\',division-1结束为@table中的Town,因为TI接受了第一个正确答案-在我看来这是最公平的方式。但对我来说,我喜欢REPLACELEFTe\u visu name,CHARINDEX'\',e\u visu name+'\',1'\',最重要的是,尽管其他的都是正确的。REPLACELEFTe\u visu name,CHARINDEX'\',e\u visu name+'\',1'\',quete simple and elegent-也很有效,ty@Cove我测试了上面所有的函数,它们在任何情况下都应该工作;。shA.t,我很感谢你分享知识,我相信你所有的例子都可以,但是我没有足够的时间来测试本主题中的所有函数。我有一项任务现在已经完成,我的主要目标是学习SQL。因此,每天晚上我都会回到这里,测试新的变体,试图了解它们是如何工作的。我想再次感谢所有人的帮助。
REPLACE(LEFT(e_vis_name, CHARINDEX('\', e_vis_name + '\', 1)), '\', '')
REPLACE(SUBSTRING(e_vis_name, 1, CHARINDEX('\', e_vis_name + '\', 1)), '\', '')
STUFF(e_vis_name + '\', CHARINDEX('\', e_vis_name + '\', 1), 512, '')
REVERSE(PARSENAME(REVERSE(REPLACE(e_vis_name, '\','.')), 1))

-- or REPLACE(REVERSE(PARSENAME(REPLACE(REVERSE(REPLACE(e_vis_name, '.', CHAR(8))), '\','.'), 1)), CHAR(8), '.')
PARSENAME(REPLACE(e_vis_name, '\','.'), LEN(e_vis_name) - LEN(REPLACE(e_vis_name, '\', '')) + 1)
-- or REPLACE(PARSENAME(REPLACE(REPLACE(e_vis_name, '.', CHAR(8)), '\','.'), LEN(e_vis_name) - LEN(REPLACE(e_vis_name, '\', '')) + 1) , CHAR(8), '.')