TSQL中的正则表达式

时间:2015-05-12 07:06:50

标签: sql-server tsql sql-server-2005

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

  • 莫斯科\方向
  • 雅罗斯拉夫\ SALES
  • 鄂木斯克\商业中心\销售

我需要在第一个\符号之后剪切所有内容以获得以下结果:

  • 莫斯科
  • 雅罗斯拉夫
  • 鄂木斯克

我该怎么做?

3 个答案:

答案 0 :(得分:5)

您可以像这样使用LEFTCHARINDEX的组合:

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,那么只需设置一个空字符串。"

我确定你可以根据自己的目的进行调整。

答案 1 :(得分:1)

有多种选择可以实现您的需求,下面是几个例子

--------------------------------------------------------------------------------
-- 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

答案 2 :(得分:1)

作为一些替代方案:

使用LEFT

REPLACE(LEFT(e_vis_name, CHARINDEX('\', e_vis_name + '\', 1)), '\', '')

使用SUBSTRING

REPLACE(SUBSTRING(e_vis_name, 1, CHARINDEX('\', e_vis_name + '\', 1)), '\', '')

使用STUFF

STUFF(e_vis_name + '\', CHARINDEX('\', e_vis_name + '\', 1), 512, '')

使用PARSENAME

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), '.')