it-swarm.com.de

Entfernen Sie in SQL Server nachfolgende Nullen aus dem Dezimalzeichen

Ich habe eine Spalte DECIMAL(9,6), die Werte wie 999,123456 unterstützt.

Wenn ich jedoch Daten wie 123,4567 einfüge, werden 123,456700

Wie entferne ich diese Nullen?

67
abatishchev

Eine decimal(9,6) speichert 6 Ziffern auf der rechten Seite des Kommas. Ob nachfolgende Nullen angezeigt werden sollen oder nicht, ist eine Formatierungsentscheidung, die normalerweise auf der Clientseite implementiert wird.

Da jedoch die SSMS-Formate float ohne nachgestellte Nullen sind, können Sie nachfolgende Nullen entfernen, indem Sie die decimal in eine float umwandeln:

select 
    cast(123.4567 as DECIMAL(9,6))
,   cast(cast(123.4567 as DECIMAL(9,6)) as float)

druckt:

123.456700  123,4567

(Mein Dezimaltrennzeichen ist ein Komma, jedoch formatiert SSMS Dezimalzeichen mit einem Punkt. Offenbar ein bekanntes Problem .)

117
Andomar

Sie können die Funktion FORMAT() (SqlAzure und Sql Server 2012+) verwenden:

SELECT FORMAT(CAST(15.12     AS DECIMAL(9,6)), 'g18')  -- '15.12'
SELECT FORMAT(CAST(0.0001575 AS DECIMAL(9,6)), 'g10')  -- '0.000158'
SELECT FORMAT(CAST(2.0       AS DECIMAL(9,6)), 'g15')  -- '2'

Seien Sie vorsichtig bei der Verwendung von FLOAT (oder REAL): Verwenden Sie nicht g17 oder größer (oder g8 oder größer mit REAL), da die begrenzte Genauigkeit der Maschinendarstellung unerwünschte Auswirkungen hat:

SELECT FORMAT(CAST(15.12 AS FLOAT), 'g17')         -- '15.119999999999999'
SELECT FORMAT(CAST(0.9 AS REAL), 'g8')             -- '0.89999998'
SELECT FORMAT(CAST(0.9 AS REAL), 'g7')             -- '0.9'

Beachten Sie außerdem, dass gemäß der Dokumentation

FORMAT setzt das Vorhandensein der .NET Framework Common Language .__ voraus. Laufzeit (CLR). Diese Funktion wird nicht entfernt, da sie von .__ abhängt. die Anwesenheit der CLR. Remoting einer Funktion, für die die CLR erforderlich ist würde einen Fehler auf dem Remote-Server verursachen.

Funktioniert auch in SqlAzure.

26
robert4
SELECT CONVERT(DOUBLE PRECISION, [ColumnName])
11
Bat_Programmer
SELECT REVERSE(ROUND(REVERSE(2.5500),1))

druckt:

2.55
6
user1959416

Ich zögerte, zum Float zu wechseln, da in meinem Dezimalzeichen möglicherweise mehr Ziffern vorhanden sind, als Float darstellen kann

FORMAT gab in Verbindung mit einem Standard-.net-Formatstring 'g8' die wissenschaftliche Notation für sehr kleine Dezimalstellen (z. B. 1e-08) zurück, was ebenfalls ungeeignet war

Mit einer benutzerdefinierten Formatzeichenfolge ( https://docs.Microsoft.com/de-de/dotnet/standard/base-types/custom-numeric-format-strings ) konnte ich erreichen, was ich wollte:

DECLARE @n DECIMAL(9,6) =1.23;
SELECT @n
--> 1.230000
SELECT FORMAT(@n, '0.######')
--> 1.23

Wenn Sie möchten, dass Ihre Nummer mindestens eine nachfolgende Null hat und 2.0 nicht zu 2 wird, verwenden Sie eine Formatzeichenfolge wie 0.0#####.

Der Dezimalpunkt ist lokalisiert, sodass Kulturen, die ein Komma als Dezimaltrennzeichen verwenden, auf eine Kommaausgabe stoßen, in der das Dezimalzeichen steht. ist

Natürlich ist dies die abschreckende Praxis, die Formatierung der Datenschicht vorzunehmen (in meinem Fall gibt es jedoch keine andere Schicht; der Benutzer führt buchstäblich eine gespeicherte Prozedur aus und speichert das Ergebnis in einer E-Mail: /)

5
Caius Jard

Am besten konvertieren Sie NICHT inFLOAToderMONEY, bevor Sie mit der Konvertierung beginnen, da die Genauigkeit möglicherweise beeinträchtigt wird. Die sicheren Wege können also so aussehen: 

CREATE FUNCTION [dbo].[fn_ConvertToString]
(
    @value sql_variant
)
RETURNS varchar(max)
AS
BEGIN
    declare @x varchar(max)
    set @x= reverse(replace(ltrim(reverse(replace(convert(varchar(max) , @value),'0',' '))),' ',0))

    --remove "unneeded "dot" if any
    set @x = Replace(RTRIM(Replace(@x,'.',' ')),' ' ,'.')
    return @x
END

wobei @value any decimal (x, y) sein kann

2
Mahmoud Moravej
Cast(20.5500 as Decimal(6,2))

sollte es tun.

2
Peter Jones

Ich hatte ein ähnliches Problem, musste aber auch den Dezimalpunkt entfernen, an dem keine Dezimalzahl vorhanden war. Hier war meine Lösung, die die Dezimalzahl in ihre Komponenten aufteilt und die Anzahl der Zeichen, die für die Dezimalzeichenfolge erforderlich sind, auf der Länge von die Bruchkomponente (ohne CASE). Um die Sache noch interessanter zu machen, wurde meine Nummer als Float ohne Dezimalzahlen gespeichert.

DECLARE @MyNum FLOAT
SET @MyNum = 700000
SELECT CAST(PARSENAME(CONVERT(NUMERIC(15,2),@MyNum/10000),2) AS VARCHAR(10)) 
+ SUBSTRING('.',1,LEN(REPLACE(RTRIM(REPLACE(CAST(PARSENAME(CONVERT(NUMERIC(15,2),@MyNum/10000),1) AS VARCHAR(2)),'0',' ')),' ','0'))) 
+ REPLACE(RTRIM(REPLACE(CAST(PARSENAME(CONVERT(NUMERIC(15,2),@MyNum/10000),1) AS VARCHAR(2)),'0',' ')),' ','0') 

Das Ergebnis ist schmerzhaft, ich weiß, aber ich bin mit viel Hilfe von den obigen Antworten dorthin gekommen.

2
Adge Cutler

Ich hatte ein ähnliches Problem und musste nachträgliche Nullen von Zahlen wie xx0000,x00000,xxx000 abschneiden.

Ich benutzte:

select LEFT(code,LEN(code)+1 - PATINDEX('%[1-Z]%',REVERSE(code))) from Tablename

Code ist der Name des Feldes mit der Nummer, die getrimmt werden soll. Hoffe das hilft jemand anderem.

1
Kazeem Muritala

Ich musste nachfolgende Nullen in meinen Dezimalzahlen entfernen, damit ich nur einen String mit einer bestimmten Länge ausgeben konnte führend Nullen

(Zum Beispiel musste ich 14 Zeichen ausgeben, so dass 142.023400 000000142.0234 wird).

Ich habe parsename, reverse und castas int verwendet, um die nachfolgenden Nullen zu entfernen:

SELECT
    PARSENAME(2.5500,2)
    + '.'
    + REVERSE(CAST(REVERSE(PARSENAME(2.5500,1)) as int))

(Um meine führenden Nullen zu erhalten, konnte ich die korrekte Anzahl von Nullen basierend auf der Länge der obigen Zeilen replizieren und diese an der Vorderseite der obigen Kette verketten.)

Ich hoffe das hilft jemandem.

1
Ali
case when left(replace(ltrim(rtrim(replace(str(XXX, 38, 10), '0',  ' '))), ' ', '0'), 1) = '.'
then '0' 
else ''
end +

replace(ltrim(rtrim(replace(str(XXX, 38, 10), '0',  ' '))), ' ', '0') +

case when right(replace(ltrim(rtrim(replace(str(XXX, 38, 10), '0',  ' '))), ' ', '0'), 1) = '.'
then '0' 
else ''
end
0
beloblotskiy

Andere Option...

Ich weiß nicht, wie effizient das ist, aber es scheint zu funktionieren und geht nicht per Float:

select replace(rtrim(replace(
       replace(rtrim(replace(cast(@value as varchar(40)), '0', ' ')), ' ', '0')
       , '.', ' ')), ' ', '.')

Die mittlere Linie entfernt nachgestellte Leerzeichen, die äußeren zwei entfernen den Punkt, wenn keine Dezimalstellen vorhanden sind

0
SQLian

es ist möglich, führende und nachfolgende Nullen in TSQL zu entfernen

  1. Konvertieren Sie es mit der TSQL-Funktion STR in string, wenn nicht string. Dann 

  2. Entfernen Sie sowohl führende als auch nachfolgende Nullen

    SELECT REPLACE(RTRIM(LTRIM(REPLACE(AccNo,'0',' '))),' ','0') AccNo FROM @BankAccount
    
  3. Mehr Infos im Forum .

0
Ishtiaq

Wie wäre es damit? Angenommen, Daten kommen als @thisData in Ihre Funktion

BEGIN
  DECLARE @thisText VARCHAR(255)
  SET @thisText = REPLACE(RTRIM(REPLACE(@thisData, '0', ' ')), ' ', '0')
  IF SUBSTRING(@thisText, LEN(@thisText), 1) = '.'
    RETURN STUFF(@thisText, LEN(@thisText), 1, '')
  RETURN @thisText
END
0
MrNazgul

Ich verstehe, dass dies ein alter Beitrag ist, aber ich möchte SQL bereitstellen, mit dem ich gekommen bin

DECLARE @value DECIMAL(23,3)
set @value = 1.2000
select @value original_val, 
    SUBSTRING(  CAST( @value as VARCHAR(100)), 
                0,
                PATINDEX('%.%',CAST(@value as VARCHAR(100)))
            )
      + CASE WHEN ROUND( 
                        REVERSE( SUBSTRING( CAST(@value as VARCHAR(100)),
                                        PATINDEX('%.%',CAST(@value as VARCHAR(100)))+1,
                                        LEN(CAST(@value as VARCHAR(100)))
                                        )
                                )
                    ,1) > 0 THEN 
            '.' 
            +  REVERSE(ROUND(REVERSE(SUBSTRING( CAST(@value as VARCHAR(100)),
                                                PATINDEX('%.%',CAST(@value as VARCHAR(100)))+1,
                                                LEN(CAST(@value as VARCHAR(100)))
                                                )
                ),1))
        ELSE '' END  AS modified_val
0
Abhi

versuche dies.

select CAST(123.456700 as float),cast(cast(123.4567 as DECIMAL(9,6)) as float)
0
Vishal Kiri

Der einfachste Weg ist, den Wert als FLOAT CAST und dann zu einem String-Datentyp CAST.

CAST(CAST(123.456000 AS FLOAT) AS VARCHAR(100))
0
Brad Raiche

Versuche dies : 

SELECT REPLACE(TRIM(REPLACE(20.5500, "0", " ")), " ", "0")

Ergibt 20,55

0
Todd