2017-11-07 2 views
0

Ich versuche, eine SQL-Abfrage für String-Manipulation auf 2 Spalten zu schreiben.SQL für Zeichenfolge Manipulation von numerischen Werten

Also im Grunde ist das Ziel, dass für Werte von 2 verschiedenen Spalten, wenn die Länge der Zahlen gleich ist und beide entgegengesetzte Vorzeichen haben, ich unbedeutende Ziffern beginnend von links fallen lassen muss. Hier ist ein Beispiel, um es ein wenig klar zu machen.

Wenn ich 2 Nummern habe, sagen wir 1123457 und -1124678, sollte die Abfrage 3457 und -4678 zurückgeben. Ich habe eine Funktion, um das zu tun, aber es scheint ewig zu dauern, da das String-Manipulation auf einer Zeile-für-Zeile-Basis macht. Hat jemand Erfahrung damit? Und wenn ja, kannst du bitte helfen?

Dank

+0

Konnten Sie Ihren vorhandenen Code bekannt geben? – Cowthulhu

+0

können Sie bitte einige Beispieldaten und gewünschte Ergebnisse posten .. nur um klar zu sein, was Sie erreichen wollen .. – Harry

+0

Es ist definitiv ein effizienter, dies zu erreichen, und versuchen Sie definitiv while Schleifen in SQL zu vermeiden. Ich werde versuchen, dir eine Antwort zu geben. – DaniDev

Antwort

0

Zunächst, wenn einige komplexe Logik zu schreiben entscheiden, was Sie brauchen, um herauszufinden, welche Werkzeuge zur Verfügung stehen. String-Manipulationen, um Zahlen zu verarbeiten, sollten Code-Geruchsalarmglocken in allen Sprachen auslösen.

Sie können hier bis zu verschiedenen SQL Server-Funktionen lesen: https://docs.microsoft.com/en-us/sql/t-sql/functions/mathematical-functions-transact-sql

Sie können auch im Internet nach Lösungen suchen. Ich hatte für "Finden Sie SQL Server Anzahl der Stellen in der Zahl" zu suchen, um diesen Artikel zu finden: Counting the number of digits in column

Der Code:

DECLARE @Sample TABLE (Num1 INT, Num2 INT) 
INSERT INTO @Sample 
VALUES(1123457, -1124678), (-1223457, 1124678), (-1223457, -1124678), (0, 0) 

;WITH Step1 AS(
    -- Determine Number properties 
    SELECT Num1, Num2, ABS(Num1) AS Num1Abs, ABS(Num2) AS Num2Abs, 
     SIGN(Num1) AS Num1Sign, 
     SIGN(Num2) AS Num2Sign, 
     (CASE WHEN LEN(ABS(Num1)) = LEN(ABS(Num2)) THEN 1 ELSE 0 END) AS LenMatchFlag 
    FROM @Sample 
), 
Step2 AS(
    -- Find all possible significant digit matches of two numbers 
    SELECT Num1, Num2, Num1Abs, Num2Abs, Num1Sign, Num2Sign, NumDigits, 
     ROW_NUMBER() OVER(PARTITION BY Num1Abs, Num2Abs ORDER BY NumDigits ASC) AS BestMatch 
    FROM Step1 
     -- Possible number of significant digits 
     CROSS JOIN (VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9)) AS NumLengths(NumDigits) 
    WHERE 
     LenMatchFlag = 1 
     AND Num1Sign = Num2Sign * -1 AND Num1Sign <> 0 
     AND ROUND(Num1Abs, -NumDigits, 1) = ROUND(Num2Abs, -NumDigits, 1) 
), 
Step3 AS(
    -- Return the best match, and calculate outpu values 
    SELECT ((Num1Abs - ROUND(Num1Abs, -NumDigits, 1)) * Num1Sign) AS NewNum1, 
     ((Num2Abs - ROUND(Num2Abs, -NumDigits, 1)) * Num2Sign) AS NewNum2, 
     * 
    FROM Step2 
    WHERE BestMatch = 1 
) 
SELECT 'Changed', NewNum1, NewNum2, Num1, Num2 
FROM Step3 
UNION ALL 
SELECT 'UnChanged', Num1, Num2, Num1, Num2 
FROM Step1 
WHERE NOT(
    LenMatchFlag = 1 
    AND Num1Sign = Num2Sign * -1 AND Num1Sign <> 0 
    ) 

Ausgang:

  NewNum1  NewNum2  Num1  Num2 
--------- ----------- ----------- ----------- ----------- 
Processed 3457  -4678  1123457  -1124678 
Processed -223457  124678  -1223457 1124678 
UnChanged -1223457 -1124678 -1223457 -1124678 
UnChanged 0   0   0   0 

Hinweis: Wenn Wenn Sie Nummern mit mehr als 9 Ziffern haben, müssen Sie weitere Werte zu NumLengths Liste hinzufügen

Hinweis2: um zu sehen, welche Werte von jedem Berechnungsschritt zurückgegeben werden, können Sie die letzte SELECT ändern, um eine bestimmte Tabelle, z. SELECT * FROM Step1

+0

Vielen Dank Alex. das ist genau das, was ich wollte! nur eine weitere kurze Frage, obwohl es mir irgendwie schwer fällt, dies in eine Funktion umzuwandeln. Ich brauche es als eine Funktion, damit ich es an den Tisch anschließen kann. Irgendwelche Gedanken darüber, wie das möglich ist? – Dennyc

+0

@Dennyc, was sind die Probleme, vor denen Sie stehen? – Alex

+0

also versuche ich, das zu einer vorhandenen Tabelle beizutreten und die neuen Werte zu ersetzen: etwas wie dieses: wählen a.first_clm, a.second_column, b.newnum1, b.newmum2 von table1 a verbinden tvf_function1 (newnum1, newnum2) b – Dennyc

Verwandte Themen