Eu tenho uma coluna, DECIMAL(9,6)
ou seja, ela oferece suporte a valores como 999,123456.
Mas quando eu insiro dados como 123,4567, ele se torna 123,456700
Como remover esses zeros?
Eu tenho uma coluna, DECIMAL(9,6)
ou seja, ela oferece suporte a valores como 999,123456.
Mas quando eu insiro dados como 123,4567, ele se torna 123,456700
Como remover esses zeros?
Respostas:
A decimal(9,6)
armazena 6 dígitos no lado direito da vírgula. A exibição de zeros à direita ou não é uma decisão de formatação, geralmente implementada no lado do cliente.
Mas, como o SSMS formata float
sem zeros à direita, você pode remover os zeros à direita convertendo o decimal
para um float
:
select
cast(123.4567 as DECIMAL(9,6))
, cast(cast(123.4567 as DECIMAL(9,6)) as float)
estampas:
123.456700 123,4567
(Meu separador decimal é uma vírgula, mas o SSMS formata decimal com um ponto. Aparentemente, um problema conhecido .)
Você pode usar a FORMAT()
função (SqlAzure e Sql Server 2012+):
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'
Tenha cuidado ao usar com FLOAT (ou REAL): não use g17
ou maior (ou g8
ou maior com REAL), pois a precisão limitada da representação da máquina causa efeitos indesejados:
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'
Além disso, observe que, de acordo com a documentação :
FORMAT depende da presença do .NET Framework Common Language Runtime (CLR). Esta função não será remota, pois depende da presença do CLR. A comunicação remota de uma função que requer o CLR causaria um erro no servidor remoto.
Funciona no SqlAzure também.
SELECT CONVERT(DOUBLE PRECISION, [ColumnName])
Eu estava relutante em lançar para flutuar devido ao potencial de mais dígitos estarem no meu decimal do que o flutuante pode representar
FORMAT
quando usado com uma string de formato .net padrão, 'g8' retornou a notação científica em casos de decimais muito pequenos (por exemplo, 1e-08), que também era inadequada
Usar uma string de formato personalizado ( https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-numeric-format-strings ) me permitiu alcançar o que eu queria:
DECLARE @n DECIMAL(9,6) =1.23;
SELECT @n
--> 1.230000
SELECT FORMAT(@n, '0.######')
--> 1.23
Se você quiser que seu número tenha pelo menos um zero à direita, para que 2.0 não se torne 2, use uma string de formato como 0.0#####
O ponto decimal é localizado, então as culturas que usam uma vírgula como separador decimal encontrarão uma saída de vírgula onde o. é
Claro, esta é a prática desencorajadora de ter a camada de dados fazendo a formatação (mas no meu caso não há outra camada; o usuário está literalmente executando um procedimento armazenado e colocando o resultado em um e-mail: /)
SELECT REVERSE(ROUND(REVERSE(2.5500),1))
estampas:
2.55
Cast(20.5500 as Decimal(6,2))
deve fazer isso.
Experimente isto:
SELECT REPLACE(TRIM(REPLACE(20.5500, "0", " ")), " ", "0")
Dá 20,55
0.000
tornou - se .
. aqui está a correção SELECT REPLACE(RTRIM(REPLACE(20.5500, "0", " ")), " ", "0")
para cortar apenas zeros à direita
Eu tive um problema semelhante, mas também fui obrigado a remover o ponto decimal onde nenhum decimal estava presente, aqui estava minha solução que divide o decimal em seus componentes e baseia o número de caracteres que leva da string do ponto decimal no comprimento de o componente da fração (sem usar CASE). Para tornar as coisas ainda mais interessantes, meu número foi armazenado como um flutuante sem seus decimais.
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')
O resultado é doloroso, eu sei, mas cheguei lá, com muita ajuda das respostas acima.
A melhor maneira é NÃO converter para FLUTUANTE ou DINHEIRO antes da conversão devido à chance de perda de precisão. Portanto, as formas seguras podem ser mais ou menos assim:
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
onde @value pode ser qualquer decimal (x, y)
sp_
para procedimento armazenado, fn_
para funções, tbl
para tabelas e assim on ... isso não é um requisito, mas são as melhores práticas para organizar nossos bancos de dados.
Eu tive um problema semelhante, precisei cortar os zeros à direita de números como xx0000,x00000,xxx000
Eu usei:
select LEFT(code,LEN(code)+1 - PATINDEX('%[1-Z]%',REVERSE(code))) from Tablename
Código é o nome do campo com o número a ser aparado. Espero que isso ajude mais alguém.
Outra opção...
Não sei o quão eficiente isso é, mas parece funcionar e não passa por flutuação:
select replace(rtrim(replace(
replace(rtrim(replace(cast(@value as varchar(40)), '0', ' ')), ' ', '0')
, '.', ' ')), ' ', '.')
A linha do meio remove os espaços finais, as duas externas removem o ponto se não houver dígitos decimais
Eu precisava remover zeros à direita nas minhas casas decimais para que eu pudesse mostrar uma string de um determinado comprimento com apenas líder zeros à
(por exemplo, eu precisava imprimir 14 caracteres para que 142.023400 se tornasse 000000142.0234),
Usei parsename
, reverse
e cast
as int
para remover os zeros finais:
SELECT
PARSENAME(2.5500,2)
+ '.'
+ REVERSE(CAST(REVERSE(PARSENAME(2.5500,1)) as int))
(Para obter meus zeros à esquerda, eu poderia replicar o número correto de zeros com base no comprimento do acima e concatená-lo na frente do acima)
Espero que isso ajude alguém.
é possível remover zeros à esquerda e à direita em TSQL
Converta em string usando a função STR TSQL se não for string, então
Remova os zeros à esquerda e à direita
SELECT REPLACE(RTRIM(LTRIM(REPLACE(AccNo,'0',' '))),' ','0') AccNo FROM @BankAccount
Mais informações no fórum .
REPLACE(RTRIM(REPLACE(REPLACE(RTRIM(REPLACE(X,'0',' ')),' ','0'),'.',' ')),' ','.')
Que tal agora? Supondo que os dados entrem em sua função como @thisData:
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
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
Eu entendo que esta é uma postagem antiga, mas gostaria de fornecer o SQL que criei
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
tente isso.
select CAST(123.456700 as float),cast(cast(123.4567 as DECIMAL(9,6)) as float)
A maneira mais fácil é CAST o valor como FLOAT e então para um tipo de dados string.
CAST(CAST(123.456000 AS FLOAT) AS VARCHAR(100))
Experimente isto:
select Cast( Cast( (ROUND( 35.457514 , 2) *100) as Int) as float ) /100
Eu sei que este tópico é muito antigo, mas para aqueles que não usam o SQL Server 2012 ou superior ou não podem usar a função FORMAT por algum motivo, o seguinte funciona.
Além disso, muitas das soluções não funcionaram se o número fosse menor que 1 (por exemplo, 0,01230000).
Observe que o seguinte não funciona com números negativos.
DECLARE @num decimal(28,14) = 10.012345000
SELECT PARSENAME(@num,2) + REPLACE(RTRIM(LTRIM(REPLACE(@num-PARSENAME(@num,2),'0',' '))),' ','0')
set @num = 0.0123450000
SELECT PARSENAME(@num,2) + REPLACE(RTRIM(LTRIM(REPLACE(@num-PARSENAME(@num,2),'0',' '))),' ','0')
Retorna 10.012345 e 0.012345 respectivamente.
Experimente isto:
select isnull(cast(floor(replace(rtrim(ltrim('999,999.0000')),',','')) as int),0)
999999
, o OP está pedindo para remover os zeros à direita.
Uma coluna DECIMAL (9,6) será convertida em float sem perda de precisão, então CAST (... AS float) fará o truque.
@HLGEM: dizer que float é uma escolha ruim para armazenar números e "Nunca use float" não é correto - você só precisa saber seus números, por exemplo, medições de temperatura funcionariam bem como floats.
@abatishchev e @japongskie: prefixos na frente de procs e funções armazenados em SQL ainda são uma boa ideia, se não forem necessários; os links que você mencionou apenas instruem a não usar o prefixo "sp_" para procedimentos armazenados que você não deve usar; outros prefixos são adequados, por exemplo, "usp_" ou "spBob_"
Referência: "Todos os inteiros com 6 ou menos dígitos decimais significativos podem ser convertidos em um valor de ponto flutuante IEEE 754 sem perda de precisão": https://en.wikipedia.org/wiki/Single-precision_floating-point_format