T-SQL에서 쉼표로 숫자를 어떻게 형식화합니까?


202

sp_spaceused데이터베이스에서 일부 테이블의 데이터 / 인덱스 공간 비율을 확인하기 위해 일부 관리 쿼리를 실행 하고 SQL Server 2008에서 결과를 컴파일 하고 있습니다. 물론 나는 결과에 많은 종류의 숫자를 얻었고 내 눈은 광택을 내기 시작했습니다. 모든 숫자를 쉼표로 형식화 할 수 있다면 정말 편리합니다 (987654321은 987,654,321이됩니다). 수년 동안 SQL Server를 사용해 왔지만 프레젠테이션 레이어에서 대부분의 시간을 포맷 한 이후로이 문제가 발생하지 않았지만이 경우 SSMS의 T-SQL 결과 프레젠테이션입니다.

나는 이것을 해결하기 위해 간단한 CLR UDF를 만드는 것을 고려했지만, 평범한 오래된 T-SQL에서는 이것이 가능 해야하는 것처럼 보입니다. 그래서 여기에 질문을 제기 할 것입니다-바닐라 T-SQL에서 숫자 서식을 어떻게 사용합니까?


7
"보고서-> 테이블 별 디스크 사용량"이 미학적으로 만족스러운 방법으로 필요한 기능을 수행합니까?
Martin Smith

1
@ 마틴-정말 멋진! 존재하는지도 몰랐습니다. 나는 거의 10 년 동안 DBA 스크립트를 가지고 다녔기 때문에 완전히 놓쳤다. 아직도, 나는이 질문이 stackoverflow에 관한 T-SQL 지식 기반의 중요한 부분이라고 생각하지만 내 특정 문제에 대해서는 이것이 매우 편리합니다.
mattmc3

8
SQL Server 2012 +에서 FORMAT () 함수를 사용할 수 있습니다. 예 : '#, ##. 000'msdn.microsoft.com
en

답변:


188

SQL Server 2012 이상에서는 숫자가 쉼표로 형식화됩니다.

select format([Number], 'N0')

0원하는 소수점 이하 자릿수로 변경할 수도 있습니다 .


16
이것은 format기능 이 도입 된 이래로 가장 좋은 대답 입니다.
mattmc3

세 번째 (선택적) 매개 변수에 주목할 가치가 culture있습니다.
Samuele Colombo

영업 이익은 2008 SQL 서버를 지정
foremaro

254

프레젠테이션 계층에서 형식화를 수행해야한다고 말하는 OP를 포함한 모든 사람에게 동의하지만이 형식화는로 money변환 한 다음로 변환하여 T-SQL에서 수행 할 수 있습니다 varchar. 그러나 여기에는로 끝나는 후행 소수점이 포함됩니다 SUBSTRING.

SELECT CONVERT(varchar, CAST(987654321 AS money), 1)

12
일반적으로 다른 곳에서 서식을 지정해야한다는 데 동의하지만 모두 날짜 서식 기능을 당연한 것으로 간주합니다. 여기에 표시된대로 쉼표 삽입을 수행 할 수 있습니다. +1.
EBarr

4
그러나 다른 mony 형식 스타일에서는 작동하지 않습니다. 스위스에서는 Money를 다음과 같은 형식으로 작성합니다. 987'654'321.00 어떻게해야합니까?
다니엘

6
SELECT REPLACE (CONVERT (varchar, CAST (987654321 AS money), 1), ',', '' '')를 대체 할 수 있습니다.
Hoody

4
가능한 경우 프레젠테이션 계층에서 서식을 지정해야한다는 데 동의하지만, Ignite / DPA 경고와 같이받는 전자 메일이 프레젠테이션 계층 인 경우가 있습니다. 이와 같은 장소에 쉼표를 넣는 유일한 방법은 SQL을 통하는 것입니다. 이러한 경우에는 쉼표를 많이 사용하는 것이 매우 도움이됩니다.
PseudoToad

1
모든 사람들이 "어떻게"해야하는지 말하고 싶지만, 그것은 여러분 자신의 코드를 디자인하는 것이 아닙니다. 모든 사람이 "해야 할 것"만 행했다면, 우리는 최소한의 소란과 노력으로 문제를 신속하게 해결하기 위해 창의력과 사물을 해킹 할 수있는 정신을 잃습니다.
Geoff Griswald

59

문자열 길이 문제를 피하기 위해 Substring 대신 Replace를 권장합니다.

REPLACE(CONVERT(varchar(20), (CAST(SUM(table.value) AS money)), 1), '.00', '')

3
돈 변환이 절대 바뀌지 않아야하지만 Replace가 Substring을 통해 제공하는 범위를 벗어나지 않을 것을 보장합니다.
Sean

48

SQL Server 2012+ 구현의 경우 FORMAT 을 사용하여 문자열 형식이 아닌 데이터 형식에 문자열 형식을 적용 할 수 있습니다.

원래 질문에서 사용자는 쉼표를 수천 구분 기호로 사용하는 기능을 요청했습니다. A의 중복 문제로 폐쇄 , 사용자들은 통화 서식을 적용 할 수있는 방법을 물어 봤다. 다음 쿼리는 두 작업을 모두 수행하는 방법을 보여줍니다. 또한이 솔루션을보다 일반적인 솔루션으로 만들기 위해 문화를 적용하는 방법을 보여줍니다 (그리스 특수 형식을 적용하는 Tsiridis Dimitris의 기능 다루기).

-- FORMAT
-- http://msdn.microsoft.com/en-us/library/hh213505(v=sql.110).aspx
-- FORMAT does not do conversion, that's the domain of cast/convert/parse etc
-- Only accepts numeric and date/time data types for formatting. 
--
-- Formatting Types
-- http://msdn.microsoft.com/en-us/library/26etazsy.aspx

-- Standard numeric format strings
-- http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx
SELECT
    -- c => currency
    -- n => numeric
    FORMAT(987654321, N'N', C.culture) AS some_number
,   FORMAT(987654321, N'c', C.culture) AS some_currency
,   C.culture
FROM
    (
        -- Language culture names
        -- http://msdn.microsoft.com/en-us/library/ee825488(v=cs.20).aspx
        VALUES
            ('en-US')
        ,   ('en-GB')
        ,   ('ja-JP')
        ,   ('Ro-RO')
        ,   ('el-GR')
    ) C (culture);

위의 SQLFiddle


1
큰 점유율, 이것은 유용하게 올 것이다 :)
jediCouncilor

1
바이올린이 고장났습니다. 이제 말합니다String index out of range: 33
Jeff Puckett

1
@JeffPuckettII 그래, SQL Server의 바이올린이 더 이상 작동하지 않는 것은 유감입니다. 다행히 SQL Server 2012+에 연결된 쿼리 도구에 위의 내용을 붙여 넣을 수 있어야합니다.
billinkc

20

데모 1

쉼표 추가를 보여줍니다.

PRINT FORMATMESSAGE('The number is: %s', format(5000000, '#,##0'))
-- Output
The number is: 5,000,000

데모 2

쉼표와 소수점을 보여줍니다. 필요한 경우 마지막 숫자를 반올림하십시오.

PRINT FORMATMESSAGE('The number is: %s', format(5000000.759145678, '#,##0.00'))
-- Output
The number is: 5,000,000.76

적합성

SQL Server 2012+.


2
이것은 하나입니다! len (열) 및 열과 함께 작동하지만 다른 2012 + 솔루션은 그렇지 않았습니다.
Graham Laight

1
큰! 이것은 (포함, T-SQL 사용하기 위해 내가 찾던 해답 SEDE )
ashleedawg

10

아래 쿼리로 시도하십시오 :

SELECT FORMAT(987654321,'#,###,##0')

오른쪽 소수점 형식 :

SELECT FORMAT(987654321,'#,###,##0.###\,###')

3
예, 우리가 FORMAT함수를 가지고있는 올바른 방법 은 @ThomasMueller가 대답 한 것처럼 SELECT format(123456789987654321,'###,##0')또는 더 간단 select format(123456789987654321, 'N0')합니다.
mattmc3

FORMAT은 성능 악몽입니다. ​​사용하기 시작하고 의존하면 데이터베이스를 확장 할 수 없습니다. 그리고 이제는 12 가지 기능이 내장되어있어 탈출 할 수 없습니다. FORMAT을 사용하지 마십시오.
Pxtl

9
SELECT REPLACE(CONVERT(varchar(20), (CAST(9876543 AS money)), 1), '.00', '')

출력 = 9,876,543

9876543을 열 이름으로 바꿀 수 있습니다.


7

위의 머니 트릭을 시험해 보았고 유효 숫자가 두 개 이하인 숫자 값에 효과적입니다. 소수점 이하 자릿수를 지정하는 내 함수를 만들었습니다.

CREATE FUNCTION [dbo].[fn_FormatWithCommas] 
(
    -- Add the parameters for the function here
    @value varchar(50)
)
RETURNS varchar(50)
AS
BEGIN
    -- Declare the return variable here
    DECLARE @WholeNumber varchar(50) = NULL, @Decimal varchar(10) = '', @CharIndex int = charindex('.', @value)

    IF (@CharIndex > 0)
        SELECT @WholeNumber = SUBSTRING(@value, 1, @CharIndex-1), @Decimal = SUBSTRING(@value, @CharIndex, LEN(@value))
    ELSE
        SET @WholeNumber = @value

    IF(LEN(@WholeNumber) > 3)
        SET @WholeNumber = dbo.fn_FormatWithCommas(SUBSTRING(@WholeNumber, 1, LEN(@WholeNumber)-3)) + ',' + RIGHT(@WholeNumber, 3)



    -- Return the result of the function
    RETURN @WholeNumber + @Decimal

END

4

이것은 Phil Hunt 의 답변 에 대한 의견에 속 하지만 아쉽게도 담당자가 없습니다.

숫자 문자열의 끝에서 ".00"을 제거하려면 parsename을 사용하는 것이 좋습니다. 마침표로 구분 된 문자열을 토큰 화하고 맨 오른쪽 토큰부터 요소 1로 지정된 요소를 반환합니다.

SELECT PARSENAME(CONVERT(varchar, CAST(987654321 AS money), 1), 2)

수율 "987,654,321"


3

여기 또 다른 t-sql UDF가 있습니다

CREATE FUNCTION dbo.Format(@num int)
returns varChar(30)
As
Begin
Declare @out varChar(30) = ''

  while @num > 0 Begin
      Set @out = str(@num % 1000, 3, 0) + Coalesce(','+@out, '')
      Set @num = @num / 1000
  End
  Return @out
End

2
`/* Author: Tsiridis Dimitris */
/* Greek amount format. For the other change the change on replace of '.' & ',' */
CREATE FUNCTION dbo.formatAmount  (
@amtIn as varchar(20)
) RETURNS varchar(20)
AS
BEGIN 

return cast(REPLACE(SUBSTRING(CONVERT(varchar(20), CAST(@amtIn AS money), 1),1,
LEN(CONVERT(varchar(20), CAST(@amtIn AS money), 1))-3), ',','.')
 + replace(RIGHT(CONVERT(varchar(20), CAST(@amtIn AS money), 1),3), '.',',') AS VARCHAR(20))

END

SELECT [geniki].[dbo].[formatAmount]('9888777666555.44')`

1

다음은 이전 예제 (위)의 일부 버그를 수정하고 소수점 이하 자릿수 (지정된 자릿수까지)를 처리하는 스칼라 함수입니다 (0 및 음수와 함께 작동하도록 편집). 또 다른 참고로, 위의 돈으로 캐스트 방법은 MONEY 데이터 유형의 크기로 제한되며 4 자리 이상의 십진수에서는 작동하지 않습니다. 이 방법은 훨씬 간단하지만 유연성이 떨어집니다.

CREATE FUNCTION [dbo].[fnNumericWithCommas](@num decimal(38, 18), @decimals int = 4) RETURNS varchar(44) AS
BEGIN
    DECLARE @ret varchar(44)

    DECLARE @negative bit; SET @negative = CASE WHEN @num < 0 THEN 1 ELSE 0 END

    SET @num = abs(round(@num, @decimals)) -- round the value to the number of decimals desired
    DECLARE @decValue varchar(18); SET @decValue = substring(ltrim(@num - round(@num, 0, 1)) + '000000000000000000', 3, @decimals)
    SET @num = round(@num, 0, 1) -- truncate the incoming number of any decimals
    WHILE @num > 0 BEGIN
        SET @ret = str(@num % 1000, 3, 0) + isnull(','+@ret, '')
        SET @num = round(@num / 1000, 0, 1)
    END
    SET @ret = isnull(replace(ltrim(@ret), ' ', '0'), '0') + '.' + @decValue
    IF (@negative = 1) SET @ret = '-' + @ret

    RETURN @ret
END

GO

1

또 다른 UDF는 충분히 일반적이며 특정 소수점 이하 자릿수로 반올림할지 여부를 가정하지 않습니다.

CREATE FUNCTION [dbo].[fn_FormatNumber] (@number decimal(38,18))

RETURNS varchar(50)

BEGIN
    -- remove minus sign before applying thousands seperator
    DECLARE @negative bit
    SET @negative = CASE WHEN @number < 0 THEN 1 ELSE 0 END
    SET @number = ABS(@number)

    -- add thousands seperator for every 3 digits to the left of the decimal place
    DECLARE @pos int, @result varchar(50) = CAST(@number AS varchar(50))
    SELECT @pos = CHARINDEX('.', @result)
    WHILE @pos > 4
    BEGIN
        SET @result = STUFF(@result, @pos-3, 0, ',')
        SELECT @pos = CHARINDEX(',', @result)
    END

    -- remove trailing zeros
    WHILE RIGHT(@result, 1) = '0'
        SET @result = LEFT(@result, LEN(@result)-1)
    -- remove decimal place if not required
    IF RIGHT(@result, 1) = '.'
        SET @result = LEFT(@result, LEN(@result)-1)

    IF @negative = 1
        SET @result = '-' + @result

    RETURN @result
END

0
/*
  #------------------------------------------------------------------------#
  #            SQL Query Script                                            #
  #            ----------------                                            #
  # Funcion.:  dbo.fn_nDerecha ( Numero, Pos_Enteros, Pos_Decimales )      #
  #    Numero        : es el Numero o Valor a formatear                    #
  #    Pos_Enteros   : es la cantidad posiciones para Enteros              #
  #    Pos_Decimales : es la cantidad posiciones para Decimales            #
  #                                                                        #
  # OBJETIVO:  Formatear los Numeros con Coma y Justificado a la Derecha   #
  #  Por Ejemplo:                                                          #
  #   dbo.fn_nDerecha ( Numero, 9, 2 )         Resultado = ---,---,--9.99  #
  #               dado  Numero = 1234.56       Resultado =       1,234.56  #
  #               dado  Numero = -1.56         Resultado =          -1.56  #
  #               dado  Numero = -53783423.56  Resultado = -53,783,423.56  #
  #                                                                        #
  # Autor...:  Francisco Eugenio Cabrera Perez                             #
  # Fecha...:  Noviembre 25, 2015                                          #
  # Pais....:  Republica Dominicana                                        #
  #------------------------------------------------------------------------#
*/



CREATE FUNCTION [dbo].[fn_nDerecha]
(
    -- Agregue Argumentos, para personalizar la funcion a su conveniencia
    @Numero_str    varchar(max)
   ,@Pos_Enteros   int
   ,@Pos_Decimales int
)
RETURNS varchar(max)
AS
BEGIN
  --  Declare la variable del RETURN aqui, en este caso es RESULT
  declare @RESULTADO varchar(max)
  set     @RESULTADO = '****'

  -----------------------------------------------  --
  declare @Numero_num numeric(28,12)
  set     @Numero_num =
  (
  case when isnumeric(@Numero_str) = 0 
       then 0
       else round (convert( numeric(28,12), @Numero_str), @Pos_Decimales)
  end
  )
  --  -----------------------------------------------  --
  --  Aumenta @Pos_Enteros de @RESULTADO,
  --      si las posiciones de Enteros del dato @Numero_str es Mayor...
  --
  declare   @Num_Pos_Ent int
  set       @Num_Pos_Ent = len ( convert( varchar, convert(int, abs(@Numero_num) ) ) )
  --
  declare   @Pos_Ent_Mas int
  set       @Pos_Ent_Mas =
  (
  case when @Num_Pos_Ent > @Pos_Enteros
       then @Num_Pos_Ent - @Pos_Enteros
       else 0
  end
  )
  set       @Pos_Enteros = @Pos_Enteros + @Pos_Ent_Mas
  --
  --  -----------------------------------------------  --
  declare @p_Signo_ctd       int
  set     @p_Signo_ctd       = (case when @Numero_num < 1 then 1 else 0 end)
  --
  declare @p_Comas_ctd       int
  set     @p_Comas_ctd       = ( @Pos_Enteros - 1 ) / 3
  --
  declare @p_Punto_ctd       int
  set     @p_Punto_ctd       = (case when @Pos_Decimales > 0 then 1 else 0 end)
  --
  declare @p_input_Longitud  int
  set     @p_input_Longitud  = ( @p_Signo_ctd + @Pos_Enteros ) +
                                 @p_Punto_ctd + @Pos_Decimales
  --
  declare @p_output_Longitud int
  set     @p_output_Longitud = ( @p_Signo_ctd + @Pos_Enteros   + @p_Comas_ctd )
                             + ( @p_Punto_ctd + @Pos_Decimales )
  --
  --  ===================================================================  --


  declare @Valor_str varchar(max)
  set     @Valor_str = str(@Numero_num, @p_input_Longitud, @Pos_Decimales)

  declare @V_Ent_str varchar(max)
  set     @V_Ent_str = 
  (case when @Pos_Decimales > 0 
        then substring( @Valor_str, 0, charindex('.', @Valor_str, 0) )
        else            @Valor_str end)
  --
  declare @V_Dec_str varchar(max)
  set     @V_Dec_str = 
  (case when @Pos_Decimales > 0 
        then '.' + right(@Valor_str, @Pos_Decimales)
        else '' end)
  --
  set @V_Ent_str = convert(VARCHAR, convert(money, @V_Ent_str), 1) 
  set @V_Ent_str = substring( @V_Ent_str, 0, charindex('.', @V_Ent_str, 0) )
  --


  set @RESULTADO    = @V_Ent_str + @V_Dec_str 
  --
  set @RESULTADO = ( replicate( ' ', @p_output_Longitud - len(@RESULTADO) ) + @RESULTADO )
  --

  --  ===================================================================  -

-================================================== ===================-

  RETURN @RESULTADO
END

  --  ===================================================================  --

/ *이 함수에는 3 개의 인수가 필요합니다. 첫 번째 인수는 숫자가 데이터 입력으로 사용되는 @Numero_str이고 다른 두 인수는 출력에 대한 정보의 형식이 지정되는 방식을 지정합니다.이 인수는 @Pos_Enteros 및 @Pos_Decimales입니다. 입력 인수로 전달한 숫자에 대해 표시하려는 정수 및 소수 자릿수. * /


0

FORMAT 함수가 포함되지 않은 2012 년 이전 SQL Server의 경우이 함수를 작성하십시오.

CREATE FUNCTION FormatCurrency(@value numeric(30,2))
    RETURNS varchar(50)
    AS
    BEGIN
        DECLARE @NumAsChar VARCHAR(50)
        SET @NumAsChar = '$' + CONVERT(varchar(50), CAST(@Value AS money),1)
        RETURN @NumAsChar
    END 

select dbo.FormatCurrency (12345678)는 $ 12,345,678.00을 반환합니다.

쉼표를 원하면 $를 삭제하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.