2016-03-21 5 views
-1

Ich versuche, Daten von einer Tabelle in eine andere Tabelle zu kopieren, was gut funktioniert, aber ich möchte nur bestimmte Daten aus einer der Spalten kopieren.Kopieren nur bestimmter Werte von einer Zeile in eine andere Tabelle

Insert Into Period (Invoice_No, Period_Date) 
Select Invoice_Seq_No, Inv_Comment 
From Invoices 
Where INV_Comment LIKE '%November 2015'; 

Die Inv_Comment Spalte enthält Freiform-Anmerkungen und das Datum in verschiedenen Formaten, z.B. "bezahlt am November 2015 oder" bezahlt am Aug "oder" Juli 2015 ". Was ich versuche zu tun ist, nur den" November 2015 "Teil des Kommentars in die neue Tabelle zu kopieren.

Der obige Code kopiert nur die gesamten Daten des Feldes Inv_Comment und ich möchte nur das Datum kopieren.Der Datumsteil kann in einem von drei Formaten sein: MON YYYY, DD.MM.YYYY oder nur der Monat, also MON

Wie kann ich extrahiere nur den Datumsteil, an dem ich interessiert bin?

+0

Wie viele Datumsformate gibt es? Du hast es so klingen lassen, als wäre es eine freie Form (wie für ein Kommentarfeld üblich), also lautet deine erste Frage: Wie stellst du fest, welche Teile des Kommentars überhaupt ein Datum sind? Will ist immer die letzten 13 Zeichen, oder zumindest am Ende? Und kann ein Kommentar mehrere Daten enthalten? –

+0

Hallo Alex, das Inv_Comment Feld ist kein Datum Datentyp und es enthält Kommentare einschließlich des Datums! Das Datum ist in drei Formaten "Aug YYYY, DD.MM.YYYY, nur der Monat e.i.Aug". Das ist mein Problem, ich kann nicht herausfinden, welcher Teil des Kommentars das Datum ist. Danke Dan – Dan

+0

Aber immer am Ende? Extrahieren Sie jedes Datumsformat mit einer separaten Einfügung? –

Antwort

0

Für Ihre ganz einfaches Beispiel Abfrage Sie the substr() function verwenden können, um die Länge des festen Wert unter Verwendung vom Ende des Strings zu zählen, wie das Dokument beschreibt:

Wenn Position negativ ist, dann zählt Oracle rückwärts vom Ende des Char.

So können Sie tun:

select invoice_seq_no, substr(inv_comment, -length('November 2015')) 
from invoices 
where inv_comment like '%November 2015'; 

Aber es ist klar aus den Kommentaren, die Sie wirklich alle Termine finden wollen, in verschiedenen Formaten, und nicht immer am Ende des Textes Freiform. Eine Option besteht darin, den Text wiederholt nach allen möglichen Formaten und Werten zu durchsuchen, beginnend mit dem spezifischsten (z. B. DD.MM.YYYY) und dann nach unten zu am wenigsten spezifischem (z. B. nur MON). Sie könnten nur die Sequenznummern in die Tabelle einfügen beginnen, und aktualisieren Sie dann wiederholt die Zeilen, die Werte noch nicht haben:

insert into period (invoice_no) select invoice_seq_no from invoices; 

update period p 
set period_date = (
    select case when instr(i.inv_comment, '15.09.2015') > 0 then 
    substr(i.inv_comment, instr(i.inv_comment, '15.09.2015'), length('15.09.2015')) 
    end 
    from invoices i 
    where i.invoice_seq_no = p.invoice_no 
) 
where period_date is null; 

wiederholen Sie dann das Update mit einem anderen Datum oder eine allgemeinere November 2015 Muster, usw. Aber die Angabe jedes möglichen Datums ist nicht möglich, so dass Sie reguläre Ausdrücke verwenden können. Es gibt wahrscheinlich bessere Muster für diese, sondern als Beispiel:

update period p 
set period_date = (
    select regexp_substr(i.inv_comment, '[[0-3][0-9][-./][0-1][0-9][-./][12]?[901]?[0-9]{2}') 
    from invoices i 
    where i.invoice_seq_no = p.invoice_no 
) 
where period_date is null; 

, die (oder versucht zu entsprechen) entspricht etwas suchen, wie DD.MM.YYYY, gefolgt von vielleicht:

update period p 
set period_date = (
    select regexp_substr(i.inv_comment, 
    '(Jan(uary)?|Feb(ruary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|Aug(ust)?|' 
     || 'Sep(tember)?|Oct(ober)?|Nov(ember)?|Dec(ember)?)([[:space:]]+[12]?[901]?[0-9]{2})?') 
    from invoices i 
    where i.invoice_seq_no = p.invoice_no 
) 
where period_date is null; 

die Streichhölzer kurzer oder langer Monatsname Sie haben vielleicht gemischte Fälle - Aug, Aug, AUG - also möchten Sie vielleicht use the match parameter, um es Groß-und Kleinschreibung zu machen. Dies sollte jedoch keine vollständige Lösung sein, und Sie benötigen möglicherweise weitere Formate. There are some ideas on other questions.

Sie möchten wirklich aktuelle Daten, was bedeutet, ein wenig mehr brechen, und dann angenommen fehlende Jahre - vielleicht das Jahr aus einer anderen Spalte (Bestelldatum?) Wenn es nicht in den Kommentaren, obwohl das bekommt ein bisschen chaotisch um das Jahresende herum. Aber Sie können im Prinzip dasselbe tun, indem Sie einfach jeden extrahierten Wert über to_date() mit einer Formatmaske übergeben, die dem von Ihnen verwendeten Suchausdruck entspricht.

Es wird immer Fehler geben, Tippfehler, seltsame Formatierung usw., selbst wenn dieser Ansatz die meisten Muster identifiziert, werden Sie wahrscheinlich mit einigen, die leer bleiben, und müssen manuell von einem menschlichen Blick eingestellt werden bei den Kommentaren; und einige, die einfach falsch sind. Aus diesem Grund sollten Daten nicht als Strings gespeichert werden. Wenn sie mit anderem Text vermischt werden, verschlimmert das alles noch mehr.

+0

Danke für deine Mühe und hilf Alex. Ich werde es versuchen und Sie später über das Ergebnis informieren. – Dan

-1

Hier handelt es sich um Strings, die unterschiedliche Datumsangaben enthalten.Es können mehrere String-Operationen benötigt werden.

+2

Für eine Frage getaggt [Tag: Oracle]? –

Verwandte Themen