Search code examples
sql-serverstringextractmindate

Extract Min Date from a string with several dates using SQL Server


I am trying to extract the min date from a varchar string.

The data in the field looks like this

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

Using this code

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

I get this result from the record above

6

I also get

01/01/2000

On other fields

How do I correct the code to only return the Min date within each record field?

 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's post is beyond my current ability

I have created the function, here is the code to extract the data

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

What I am not understanding is how to get the bAPUI.Notes table/field into the select statement.


Solution

  • The following uses a string parser udf. Perhaps in your data, or even just in the example, there were chr(13)'s, so I had to perform a replace(), there could be other extended characters that may need to be trapped.

    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
    

    Returns

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

    While with a quick change

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

    Returns

    5/18/2016
    

    There are millions of variations but here is mine.

    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
    

    So to apply to your data

    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
    

    I have no idea how this will perform on a large dataset