2016-05-26 13 views
1

Ich versuche, das Mindestdatum aus einer varchar Zeichenfolge zu extrahieren.Extract Min Date aus einer Zeichenfolge mit mehreren Datumsangaben mit SQL Server

Die Daten im Bereich sieht wie folgt aus

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 

diesen Code verwenden

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 

ich dieses Ergebnis erhalten aus dem Datensatz über

6 

ich auch

01/01/2000 

Auf anderen Feldern

Wie korrigiere ich den Code, um nur das Min-Datum in jedem Datensatzfeld zurückzugeben?

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 

Johns Beitrag über meine derzeitige Fähigkeit ist

ich die Funktion erstellt haben, hier ist der Code die Daten

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 

Was ich verstehen mich nicht zu extrahieren ist, wie die bAPUI bekommen .Notes Tabelle/Feld in die Select-Anweisung.

+1

Viel Glück durchführen wird. Diese Art der Analyse von Daten, die als freier Text erscheinen, ist grenzwertig unmöglich. Es gibt einfach nichts Konkretes, das Sie verwenden können, um zu identifizieren, wo ein Datum beginnt oder wo es endet.Sie könnten die Daten wahrscheinlich isolieren, aber es wäre schwierig, das zu erweitern, um den Zeitabschnitt einzuschließen. –

+0

Ist die Probe, die Sie gepostet haben, der Inhalt einer einzelnen Zeile? Oder sind das mehrere Zeilen? Einen Einblick in Ihren Tisch zu geben, wird Ihnen hier sehr gut tun. –

+0

Sean Ich mache mir keine Sorgen um die Zeit, nur das Datum. Danke – Steve

Antwort

1

Im Folgenden wird ein String-Parser UDF. Vielleicht gab es in Ihren Daten oder auch nur in dem Beispiel chr (13), also musste ich eine replace() durchführen, da könnte es andere erweiterte Zeichen geben, die möglicherweise abgefangen werden müssen.

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 

Während mit einem schnellen Wechsel

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 

Es gibt Millionen von Variationen, aber hier ist mein.

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,@[email protected],@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

auf Ihre Daten anwenden
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 

Ich habe keine Ahnung, wie diese auf einem großen Datenmenge

+0

Sofern Sie nicht auch Ihren String Splitter liefern, ist dies keine vollständige Antwort. –

+0

Ich würde empfehlen, dass Sie diesen ersetzen ersetzen. Eine Schleife dafür ist wirklich langsam. Hier sind einige bessere Optionen. http://sqlperformance.com/2012/07/t-sql-queries/split-strings Unabhängig davon erhalten Sie eine +1 von mir. –

+0

Werde einen Blick werfen. Danke für den Link. –

0

Superschneller Entwurf - Verwenden Sie CHARINDEX und LEFT, um alle Zeichen bis zum ersten Leerzeichen abzurufen, konvertieren Sie dann diesen Text in ein DATUM, und verwenden Sie dann MIN, um das EARLIEST-Datum auszuwählen.

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

+0

Meine Antwort kann völlig falsch sein, wenn das Datum anywhere in der Zeichenfolge sein könnte - ich dachte, die Zeichenfolge begann mit dem Datum – Aron

+0

erhielt diesen Fehler "Msg 241, Ebene 16, Status 1, Zeile 11 Konvertierung fehlgeschlagen beim Konvertieren von Datum und/oder Zeit von Zeichenkette " – Steve