J'ai une colonne float avec des nombres de longueurs différentes et j'essaie de les convertir en varchar.
Certaines valeurs dépassent la taille maximale de bigint, je ne peux donc pas faire quelque chose comme ça
cast(cast(float_field as bigint) as varchar(100))
J'ai essayé d'utiliser décimal, mais les nombres ne sont pas de la même taille, donc cela n'aide pas trop
CONVERT(varchar(100), Cast(float_field as decimal(38, 0)))
Toute aide est appréciée.
METTRE À JOUR:
La valeur de l'échantillon est 2.2000012095022E + 26 .
Essayez d’utiliser la fonction STR()
.
SELECT STR(float_field, 25, 5)
Une autre remarque: cette touche à gauche avec des espaces. Si cela pose un problème, combinez-le avec LTRIM
:
SELECT LTRIM(STR(float_field, 25, 5))
Le seul bit de requête que j'ai trouvé qui retourne le même numéro original EXACT est
CONVERT (VARCHAR(50), float_field,128)
Voir http://www.connectsql.com/2011/04/normal-0-microsoftinternetexplorer4.html
Les autres solutions ci-dessus arrondissent ou ajoutent parfois des chiffres à la fin
UPDATE: Selon les commentaires ci-dessous et ce que je peux voir dans https://msdn.Microsoft.com/en-us/library/ms187928.aspx :
CONVERT (VARCHAR(50), float_field,3)
Doit être utilisé dans les nouvelles versions de SQL Server (base de données Azure SQL et à partir de SQL Server 2016 RC3)
c'est la solution que j'ai finalement utilisée dans sqlserver 2012 (toutes les autres suggestions ayant l'inconvénient de tronquer une partie fractionnaire ou un autre inconvénient).
declare @float float = 1000000000.1234;
select format(@float, N'#.##############################');
sortie:
1000000000.1234
cela a l’avantage supplémentaire (dans mon cas) de faciliter la séparation et la localisation des milliers:
select format(@float, N'#,##0.##########', 'de-DE');
sortie:
1.000.000.000,1234
Sujet utile merci.
Si vous voulez comme moi supprimer le zéro non significatif, vous pouvez l'utiliser:
DECLARE @MyFloat [float];
SET @MyFloat = 1000109360.050;
SELECT REPLACE(RTRIM(REPLACE(REPLACE(RTRIM(LTRIM(REPLACE(STR(@MyFloat, 38, 16), '0', ' '))), ' ', '0'),'.',' ')),' ',',')
Convertissez d'abord en integer
, puis en string
:
cast((convert(int,b.tax_id)) as varchar(20))
Cela peut aider sans arrondir
declare @test float(25)
declare @test1 decimal(10,5)
select @test = 34.0387597207
select @test
set @test1 = convert (decimal(10,5), @test)
select cast((@test1) as varchar(12))
Select LEFT(cast((@test1) as varchar(12)),LEN(cast((@test1) as varchar(12)))-1)
float a seulement un max. précision de 15 chiffres. Les chiffres après la 15e position sont donc aléatoires et la conversion en bigint (19 chiffres maximum) ou en décimale ne vous aide pas.
Si vous utilisez une fonction CLR, vous pouvez convertir le float en une chaîne qui ressemble à celle-ci, sans les 0 supplémentaires à la fin.
[Microsoft.SqlServer.Server.SqlFunction(DataAccess = DataAccessKind.Read)]
[return: SqlFacet(MaxSize = 50)]
public static SqlString float_to_str(double Value, int TruncAfter)
{
string rtn1 = Value.ToString("R");
string rtn2 = Value.ToString("0." + new string('0', TruncAfter));
if (rtn1.Length < rtn2.Length) { return rtn1; } else { return rtn2; }
}
.
create table #temp (value float)
insert into #temp values (0.73), (0), (0.63921), (-0.70945), (0.28), (0.72000002861023), (3.7), (-0.01), (0.86), (0.55489), (0.439999997615814)
select value,
dbo.float_to_str(value, 18) as converted,
case when value = cast(dbo.float_to_str(value, 18) as float) then 1 else 0 end as same
from #temp
drop table #temp
.
value converted same
---------------------- -------------------------- -----------
0.73 0.73 1
0 0 1
0.63921 0.63921 1
-0.70945 -0.70945 1
0.28 0.28 1
0.72000002861023 0.72000002861023 1
3.7 3.7 1
-0.01 -0.01 1
0.86 0.86 1
0.55489 0.55489 1
0.439999997615814 0.439999997615814 1
.
Toutes les chaînes converties sont tronquées à 18 décimales et il n'y a pas de zéros à la fin. La précision à 18 chiffres n’est pas un problème pour nous. De plus, 100% de nos numéros FP (près de 100 000 valeurs) ont la même forme que les valeurs de chaîne, comme dans la base de données, sous forme de nombres FP.
Essayez celui-ci, devrait fonctionner:
cast((convert(bigint,b.tax_id)) as varchar(20))
select replace(myFloat, '', '')
Renvoie nvarchar si l'un des arguments d'entrée est du type de données nvarchar. sinon, REPLACE renvoie varchar.
Renvoie NULL si l'un des arguments est NULL.
tests:
null ==> [NULL]
1.11 ==> 1.11
1.10 ==> 1.1
1,00 ==> 1
0.00 ==> 0
- 1.10 ==> -1.1
0,00001 ==> 1e-005
0.000011 ==> 1.1e-005
Je viens de rencontrer une situation similaire et j'ai été surpris par l'arrondi des problèmes de «très grand nombre» présenté dans SSMS v17.9.1/SQL 2017.
Je ne suggère pas d’avoir une solution, mais j’ai observé que FORMATprésente un nombre qui semble correct. Je ne peux pas en déduire que cela réduit les problèmes d'arrondis ou est utile dans le cadre d'une fonction mathématique complexe.
Le code SQL fourni qui devrait démontrer clairement mes observations tout en permettant à d’autres de tester leur code et leurs idées le cas échéant.
WITH Units AS
(
SELECT 1.0 AS [RaisedPower] , 'Ten' As UnitDescription
UNION ALL
SELECT 2.0 AS [RaisedPower] , 'Hundred' As UnitDescription
UNION ALL
SELECT 3.0 AS [RaisedPower] , 'Thousand' As UnitDescription
UNION ALL
SELECT 6.0 AS [RaisedPower] , 'Million' As UnitDescription
UNION ALL
SELECT 9.0 AS [RaisedPower] , 'Billion' As UnitDescription
UNION ALL
SELECT 12.0 AS [RaisedPower] , 'Trillion' As UnitDescription
UNION ALL
SELECT 15.0 AS [RaisedPower] , 'Quadrillion' As UnitDescription
UNION ALL
SELECT 18.0 AS [RaisedPower] , 'Quintillion' As UnitDescription
UNION ALL
SELECT 21.0 AS [RaisedPower] , 'Sextillion' As UnitDescription
UNION ALL
SELECT 24.0 AS [RaisedPower] , 'Septillion' As UnitDescription
UNION ALL
SELECT 27.0 AS [RaisedPower] , 'Octillion' As UnitDescription
UNION ALL
SELECT 30.0 AS [RaisedPower] , 'Nonillion' As UnitDescription
UNION ALL
SELECT 33.0 AS [RaisedPower] , 'Decillion' As UnitDescription
)
SELECT UnitDescription
, POWER( CAST(10.0 AS FLOAT(53)) , [RaisedPower] ) AS ReturnsFloat
, CAST( POWER( CAST(10.0 AS FLOAT(53)) , [RaisedPower] ) AS NUMERIC (38,0) ) AS RoundingIssues
, STR( CAST( POWER( CAST(10.0 AS FLOAT(53)) , [RaisedPower] ) AS NUMERIC (38,0) ) , CAST([RaisedPower] AS INT) + 2, 0) AS LessRoundingIssues
, FORMAT( POWER( CAST(10.0 AS FLOAT(53)) , [RaisedPower] ) , '0') AS NicelyFormatted
FROM Units
ORDER BY [RaisedPower]
La réponse d'Axel modifiée un peu, car dans certains cas, elle produira des résultats indésirables.
DECLARE @MyFloat [float];
SET @MyFloat = 1000109360.050;
SELECT REPLACE(RTRIM(REPLACE(REPLACE(RTRIM((REPLACE(CAST(CAST(@MyFloat AS DECIMAL(38,18)) AS VARCHAR(max)), '0', ' '))), ' ', '0'),'.',' ')),' ','.')
Sélectionner
cast (replace (convert (décimal (15,2), acs_daily_debit), '.', ',') comme varchar (20))
de acs_balance_details
Basé sur la réponse moléculaire:
DECLARE @F FLOAT = 1000000000.1234;
SELECT @F AS Original, CAST(FORMAT(@F, N'#.##############################') AS VARCHAR) AS Formatted;
SET @F = 823399066925.049
SELECT @F AS Original, CAST(@F AS VARCHAR) AS Formatted
UNION ALL SELECT @F AS Original, CONVERT(VARCHAR(128), @F, 128) AS Formatted
UNION ALL SELECT @F AS Original, CAST(FORMAT(@F, N'G') AS VARCHAR) AS Formatted;
SET @F = 0.502184537571209
SELECT @F AS Original, CAST(@F AS VARCHAR) AS Formatted
UNION ALL SELECT @F AS Original, CONVERT(VARCHAR(128), @F, 128) AS Formatted
UNION ALL SELECT @F AS Original, CAST(FORMAT(@F, N'G') AS VARCHAR) AS Formatted;