2017-04-05 6 views
0

Ich schreibe eine skriptbasierte Berechnungsansicht auf HANA mit SQL. Auf der Suche nach einigen Performance-Booster-Alternativen für die Logik, die ich in einer While-Schleife implementiert habe. Die vereinfachte Version des Codes finden Sie weiter unten.HANA SQL CTE WHERE BEDINGUNG

Es wird versucht, für Anbieter aus der Tabelle A.

Bitte Geduld mit mir für ungenaue Syntax ähnlich aussehende Anbieter in Tabelle B zu erhalten.

v = select vendor, vendorname from A; 

while --set a counter here 
    vendorname = capture the record from v for row number represented by counter here 
    t = select vendor, vendorname from v where (read single vendor from counter row) 
     union all 
     select vendor, vendorname from B where contains(vendorname,:vendorname,fuzzy(0.3)) 
     union all 
     select vendor, vendorname from t 
endwhile 

Diese Abfrage wird beendet, wenn Tausende von Datensätzen in beiden Tabellen vorhanden sind. Nachdem ich einige Blogs gelesen hatte, wurde mir klar, dass ich in eine falsche Richtung gehe, die Loop verwendet.

Um das etwas schneller zu machen, stieß ich auf etwas namens CTE.

Wenn ich versucht habe, den gleichen Code mit CTE zu implementieren, darf ich das nicht tun. Beispielcode, den ich versuche zu schreiben, ist unten. Kann mir bitte jemand helfen, das richtig zu machen? Die Syntax wird vom System nicht akzeptiert.

 t = with mytab ("Vendor", "VendorName")  
      AS (select "Vendor", "VendorName" from "A" WHERE ("Updated_Date" >= :From_Date AND "Updated_Date" <= :To_Date)) 
      select * from "B" WHERE CONTAINS ("VendorName", mytab."VendorName",FUZZY(0.3)); 

Der SQL-Fehler für diese Syntax: SQL: ungültige Kennung: MyTab

ich wissen möchte:

  1. Ob eine solche Operation mit CTE erlaubt ist. Wenn ja, wie lautet die korrekte Syntax in HANA SQL?

  2. Wenn nein, wie erreiche ich das gewünschte Ergebnis, ohne eine Tabelle durchlaufen zu müssen?

Danke,

Anup

Antwort

0

CTE in SAP HANA erlaubt sind - möchten Sie vielleicht die HANA SQL-Referenz überprüfen, ob Sie für Syntax suchen sind.

Aber wie Sie auch in einem SQLScript-Kontext sind, können Sie stattdessen auch Tabellenvariablen verwenden.

Worüber ich mir nicht sicher bin, ist, was Sie eigentlich versuchen zu tun. Geben Sie nach Möglichkeit eine Beschreibung Ihres Nutzungsszenarios an.


Ok, basierend auf Ihren Kommentaren könnte der folgende Ansatz für Sie arbeiten. Hinweis, in meinem Beispiel verwende ich eine Kopie der Systemtabelle USERS, so dass Sie die Abfrage an Ihre Tabellen anpassen müssen.

do 
begin 
declare user_names nvarchar(5000); 

    select string_agg(user_name,' ') into user_names 
    from cusers 
    where user_name in ('SYS', 'SYSTEM'); 

    select * 
    from cusers 
    where contains (user_name, :user_names, fuzzy(0.3)); 

end;  

Was ich hier zu tun ist, um alle potentiellen Namen zu erhalten, für die ich user_names eine Fuzzy-Suche in eine Variable tun wollen (durch ein Leerzeichen getrennt). Dazu nutze ich die Aggregationsfunktion STRING_AGG().
Nachdem die erste Anweisung abgeschlossen ist, enthält :user_namesSYSTEM SYS in meinem Beispiel.Jetzt , CONTAINS ermöglicht sofort mehrere Spalten für mehrere Suchbegriffe zu suchen (Sie können in der Referenzdokumentation für Details hier erneut prüfen), so

CONTAINS (<column_name>, 'term1 term2 term3') 

sieht für alle drei Begriffe in der Säule .

Damit füttern wir die Zeichenfolge SYS SYSTEM in die zweite Abfrage und die CONTAINS Klausel.

Das funktioniert gut für mich, vermeidet einen Beitritt und läuft über den Tisch, um nur einmal gesucht werden.

BTW: keine Ahnung, wo Sie diese Aussage über Tabellenvariablen in schreibgeschützten Verfahren von - es ist falsch. Natürlich können Sie Tabellenvariablen verwenden, in der Tat wird empfohlen, sie zu verwenden.

+0

Danke Lars. In der neuen Abfrage ist ** mytab. "VendorName" ** nicht korrekt Syntax. Ich würde gerne wissen, ob CTEs Bereiche von Mytab in welchem ​​Zustand erlauben. Funktionell ist alles, was ich suche, ein vlookup von Tabelle A in Tabelle B durch eine unscharfe Suche (was mehr als ein Ergebnis in Tabelle B für jeden Eintrag in Tabelle A bedeutet) und die Ergebnisse von Tabelle B gegen jeden Eintrag in Tabelle A abbildet Kannst du mir bitte raten, wie ich es ohne while loop machen kann? –

+0

Und soweit es sich um * Tabellenvariablen * handelt, können diese nicht in "schreibgeschützten" Prozeduren wie Berechnungsansichten verwendet werden. Auch bei ** Tabellenvariablen ** bezweifle ich, ob ich mein Szenario ohne Loops erfüllen kann. Was ist der beste Weg, um die Leistung zu verbessern? –

+0

Danke, das hilft teilweise, aber mit diesem Ansatz kann ich das Suchergebnis nicht einem bestimmten Benutzer zuordnen. Nehmen wir an, es gibt zwei Ergebnisse (SY und SYST), die mit SYS übereinstimmen, und ein Ergebnis (SYSTEMS), das mit SYSTEM übereinstimmt. Alles, was ich mit dieser Abfrage bekomme, sind SY, SYST und SYSTEMS. Aber ich kann nicht zuordnen, welches zu welchem ​​passt, wenn ich nicht die Benutzer in **: user_names ** durchlaufe. –