需要从sqlserver中的字符串中提取子字符串

时间:2017-04-04 05:22:19

标签: sql-server

我有问题提取日期,在数据为varchar的(mar2017)中表示。我需要用'('')'除去'('')'来提取文本,并且需要将提取的日期转换为2列,输出应该如下例所示: ouput_column应为:

startdate           enddate
01-mar-2017        30-mar-2017

其中输入数据如下例所示:

input_column:
(mar-17)diesel charges for the mention office
(nov2016)diesel charges for the mention office
(mar-2015 to nov-2015)diesel charges for the mention office

1 个答案:

答案 0 :(得分:0)

我读了这个问题并尝试了一下。

DECLARE @SampleData AS TABLE 
(
   Description nvarchar(200)
)
INSERT INTO @SampleData
VALUES ('(mar-17)diesel charges for the mention office'), ('(nov2016)diesel charges for the mention office'), 
('(mar-2015 to july-2015)diesel charges for the mention office'), ('(july-2015 to nov-2015)diesel charges for the mention office to')

---- Extract start date, end date from string
; WITH temps AS 
(
   SELECT sd.Description, 
     CASE 
         WHEN CharIndex('to', sd.Description, 1) = 0 OR CharIndex('to', sd.Description, 1) > CharIndex(')', sd.Description, 1)
                THEN SUBSTRing (sd.Description, CharIndex('(', sd.Description, 1) + 1, CharIndex(')', sd.Description, 1) - CharIndex('(', sd.Description, 1) - 1)
         ELSE SUBSTRing (sd.Description, CharIndex('(', sd.Description, 1) + 1, CharIndex('to', sd.Description, 1) - CharIndex('(', sd.Description, 1) - 1)       
     END AS StartDate,
     CASE 
         WHEN CharIndex('to', sd.Description, 1) = 0 OR CharIndex('to', sd.Description, 1) > CharIndex(')', sd.Description, 1)
                THEN SUBSTRing (sd.Description, CharIndex('(', sd.Description, 1) + 1, CharIndex(')', sd.Description, 1) - CharIndex('(', sd.Description, 1) - 1)
         ELSE SUBSTRing (sd.Description, CharIndex('to', sd.Description, 1) + 3, CharIndex(')', sd.Description, 1) - CharIndex('to', sd.Description, 1) - 3)          
     END AS EndDate
FROM @SampleData sd
)
---- Extract string to get month - year
, tempMonthYear as 
(
      SELECT 
      *,
      LTRIM(RTRIM(REPLACE(Substring(t.StartDate,1, PATINDEX('%[0-9]%',t.StartDate) - 1),'-',''))) AS StartMonth,
      CASE 
            WHEN LEN(LTRIM(RTRIM(Substring(t.StartDate, PATINDEX('%[0-9]%',t.StartDate), len(t.StartDate) -PATINDEX('%[0-9]%',t.StartDate) + 1 )))) = 2
                THEN  '20' + LTRIM(RTRIM(Substring(t.StartDate, PATINDEX('%[0-9]%',t.StartDate), len(t.StartDate) -PATINDEX('%[0-9]%',t.StartDate) + 1 ))) 
            ELSE LTRIM(RTRIM(Substring(t.StartDate, PATINDEX('%[0-9]%',t.StartDate), len(t.StartDate) -PATINDEX('%[0-9]%',t.StartDate) + 1 ))) 
      END AS StartYear,
      LTRIM(RTRIM(REPLACE(Substring(t.EndDate,1, PATINDEX('%[0-9]%',t.EndDate) - 1),'-',''))) AS EndMonth,
      CASE 
            WHEN LEN(LTRIM(RTRIM(Substring(t.EndDate, PATINDEX('%[0-9]%',t.EndDate), len(t.EndDate) -PATINDEX('%[0-9]%',t.EndDate) + 1 )))) = 2
                THEN  '20' + LTRIM(RTRIM(Substring(t.EndDate, PATINDEX('%[0-9]%',t.EndDate), len(t.EndDate) -PATINDEX('%[0-9]%',t.EndDate) + 1 ))) 
            ELSE LTRIM(RTRIM(Substring(t.EndDate, PATINDEX('%[0-9]%',t.EndDate), len(t.EndDate) -PATINDEX('%[0-9]%',t.EndDate) + 1 ))) 
      END AS EndYear
FROM temps t
)
-- Get first day, last day of month
SELECT  tmy.Description, FORMAT(CAST(CONCAT('01-', tmy.StartMonth, '-', tmy.StartYear) AS datetime),'dd-MMM-yyyy')  AS StartDate,
      FORMAT(EOMONTH(cast(CONCAT('01-', tmy.EndMonth, '-', tmy.EndYear) AS datetime)), 'dd-MMM-yyyy') AS EndDate
FROM tempMonthYear tmy

演示链接:rextester

相关问题