使用SQL Server从包含多个日期的字符串中提取最小日期

时间:2016-05-26 18:10:42

标签: sql-server string extract mindate

我正在尝试从varchar字符串中提取最小日期。

该字段中的数据如下所示

QTY DIFFERENCE - PO LINE 6.  147 ON PO / 192 ON INVOICE

5/18/2016 4:18:52 PM by ROOFING\ebuchanan
ANDREW SANTORI ISSUED THIS PO, PLEASE SEND TO HIS QUE

5/21/2016 9:48:42 AM by ROOFING\knaylor
RE-ROUTED TO ATS

使用此代码

SELECT 
    UISeq,
    LEFT(SUBSTRING(Notes, PATINDEX('%[0-9/]%', Notes), 8000),
       PATINDEX('%[^0-9/]%', SUBSTRING(Notes, PATINDEX('%[0-9/]%', Notes), 8000) + 'X') -1) as 'MaxDate'
FROM 
    bAPUI
WHERE
    Notes IS NOT NULL
ORDER BY
    UISeq

我从上面的记录中得到了这个结果

6

我也得到了

01/01/2000

在其他领域

如何更正代码以仅返回每个记录字段中的最小日期?

 UISeq  MinDate
  2      3
  3      5
 13   4/1/2016
 15      1
 17 
 18  4/15/2016
 19     3
 20  4/15/2016
 40  05/22/16
 43  05/22/16
 54  5/18/16

John的帖子超出了我目前的能力

我已经创建了这个函数,这里是提取数据的代码

Declare @Str varchar(max);

Select @Str as Notes, Min(Key_Value)

from bAPUI, [dbo].[SA-udf-Str-Parse](replace(@Str,char(13),' '),' ')

Where Key_Value like '%/%'
  and len(Key_Value)>=10

我不理解的是如何将bAPUI.Notes表/字段放入select语句。

2 个答案:

答案 0 :(得分:1)

以下使用字符串解析器udf。也许在您的数据中,或者甚至在示例中,都有chr(13),所以我必须执行replace(),可能还有其他可能需要被捕获的扩展字符。

Declare @Str varchar(max)
Set @Str='QTY DIFFERENCE - PO LINE 6.  147 ON PO / 192 ON INVOICE

5/18/2016 4:18:52 PM by ROOFING\ebuchanan
ANDREW SANTORI ISSUED THIS PO, PLEASE SEND TO HIS QUE

5/21/2016 9:48:42 AM by ROOFING\knaylor
RE-ROUTED TO ATS'

Select * from [dbo].[udf-Str-Parse](replace(@Str,char(13),' '),' ')
Where Key_Value like '%/%'
  and len(Key_Value)>=10

返回

Key_PS  Key_Value
13      5/18/2016
28      5/21/2016

快速更改

Select Min(Key_Value) from [dbo].[udf-Str-Parse](replace(@Str,char(13),' '),' ')
Where Key_Value like '%/%'
  and len(Key_Value)>=10

返回

5/18/2016

有数以百万计的变化,但这是我的。

CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@delimeter varchar(10))
--Usage: Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
--       Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')
--       Select * from [dbo].[udf-Str-Parse]('id26,id46|id658,id967','|')

Returns @ReturnTable Table (Key_PS int IDENTITY(1,1) NOT NULL , Key_Value varchar(500))

As

Begin
   Declare @intPos int,@SubStr varchar(500)
   Set @IntPos = CharIndex(@delimeter, @String)
   Set @String = Replace(@String,@delimeter+@delimeter,@delimeter)
   While @IntPos > 0
      Begin
         Set @SubStr = Substring(@String, 0, @IntPos)
         Insert into @ReturnTable (Key_Value) values (@SubStr)
         Set @String = Replace(@String, @SubStr + @delimeter, '')
         Set @IntPos = CharIndex(@delimeter, @String)
      End
   Insert into @ReturnTable (Key_Value) values (@String)
   Return 
End

所以要申请数据

Select UISeq,
      ,MinDate=(Select Min(Key_Value) from [dbo].[udf-Str-Parse](replace(Notes,char(13),' '),' ') Where Key_Value like '%/%' and len(Key_Value)>=10) 
FROM  bAPUI
WHERE Notes IS NOT NULL
ORDER BYUISeq

我不知道这将如何在大型数据集上执行

答案 1 :(得分:0)

超快速草稿 - 使用CHARINDEX和LEFT检索第一个空格的所有字符,然后将该文本转换为DATE,然后使用MIN选择EARLIEST日期。

enter image description here

select @str as string ,left(@str,CHARINDEX(' ',@str)) -- Get the position of the first space, then select all characters up to the space ,MIN(convert(date,left(@str,CHARINDEX(' ',@str)))) -- Convert the selected characters to a date and then use MIN to select earliest date