web-dev-qa-db-fra.com

Comment convertir un nombre en une chaîne formatée numérique séparée par des virgules?

Existe-t-il un moyen simple de convertir un nombre (dans mon cas un entier) en une chaîne nvarchar séparée par des virgules?

Par exemple, si j'avais une valeur int de 1000000 stocké dans un champ, comment puis-je le convertir en une chaîne nvarchar avec le résultat en sortie de "1 000 000"?

Je pourrais facilement écrire une fonction pour ce faire, mais je voulais être sûr qu'il n'y avait pas de moyen plus simple impliquant un appel à CAST ou CONVERT.

29
RLH

Pour SQL Server 2012 , ou version ultérieure, une solution plus simple consiste à utiliser FORMAT ()Documentation .
PAR EXEMPLE:

SELECT Format(1234567.8, '##,##0') 

Résulte en: 1,234,568

21
Jacob Thomas

La raison pour laquelle vous ne trouvez pas d'exemples simples sur la façon de procéder dans T-SQL est qu'il est généralement considéré comme une mauvaise pratique d'implémenter la logique de formatage dans le code SQL. Les SGBDR ne sont tout simplement pas conçus pour la présentation. Bien qu'il soit possible de faire un formatage limité, il est presque toujours préférable de laisser l'application ou l'interface utilisateur gérer le formatage de ce type.

Mais si vous devez (et parfois nous devons!) Utilisez T-SQL, convertissez votre int en argent et convertissez-le en varchar, comme ceci:

select convert(varchar,cast(1234567 as money),1)

Si vous ne voulez pas les décimales de fin, procédez comme suit:

select replace(convert(varchar,cast(1234567 as money),1), '.00','')

Bonne chance!

53
Michael Ames

Rapide et sale pour int à nnn, nnn ...

declare @i int = 123456789
select replace(convert(varchar(128), cast(@i as money), 1), '.00', '')
>> 123,456,789
3
Alex K.

Bien que le formatage appartient à la couche Présentation, SQL Server 2012 et les versions supérieures fournissent la fonction FORMAT () qui fournit l'un des moyens les plus rapides et les plus simples de formater la sortie. Voici quelques conseils et exemples:

Syntaxe: Format( value, format [, culture ] )

Renvoie: la fonction Format renvoie une chaîne NVarchar formatée au format spécifié et avec une culture facultative. (Renvoie NULL pour une chaîne de format non valide.)

Remarque: La fonction Format () est cohérente dans tous les langages CLR/tous les langages .NET et offre une flexibilité maximale pour générer une sortie formatée.

Voici quelques types de formats pouvant être obtenus à l'aide de cette fonction:

  • Formatage numérique/monétaire - 'C' pour la devise, 'N' sans symbole monétaire, 'x' pour les décimales hexa.

  • Formatage date/heure - date courte 'd', date longue 'D', date/heure complète courte 'f', date complète longue 'F'/time, 't' short time, 'T' long time, 'm' month + day, 'y' year + month.

  • Formatage personnalisé - vous pouvez former votre propre format personnalisé en utilisant certains symboles/caractères, tels que jj, mm, aaaa, etc. (pour les dates). hachage (#) symboles monétaires (£ $ etc.), virgule (,) et ainsi de suite. Voir les exemples ci-dessous.

Exemples:

Exemples de Numérique/Devise intégré Formats:

   select FORMAT(1500350.75, 'c', 'en-gb') --> £1,500,350.75
   select FORMAT(1500350.75, 'c', 'en-au') --> $1,500,350.75
   select FORMAT(1500350.75, 'c', 'en-in') --> ₹ 15,00,350.75

Exemples de Date intégrée Formats:

   select FORMAT(getdate(), 'd', 'en-gb') --> 20/06/2017
   select FORMAT(getdate(), 'D', 'fr-fr') --> mardi 20 juin 2017
   select FORMAT(getdate(), 'F', 'en-us') --> Tuesday, June 20, 2017 10:41:39 PM
   select FORMAT(getdate(), 'T', 'en-gb') --> 22:42:29

Exemples de Formatage personnalisé:

   select FORMAT(GETDATE(), 'ddd  dd/MM/yyyy')  --> Tue 20/06/2017
   select FORMAT(GETDATE(), 'dddd dd-MMM-yyyy') --> Tuesday 20-Jun-2017
   select FORMAT(GETDATE(), 'dd.MMMM.yyyy HH:mm:ss') --> 20.June.2017 22:47:20
   select FORMAT(123456789.75,'$#,#.00')  --> $123,456,789.75
   select FORMAT(123456789.75,'£#,#.0')   --> £123,456,789.8

Voir MSDN pour plus d'informations sur la fonction FORMAT ().

Pour SQL Server 2008 ou inférieur convertissez la sortie en MONEY d'abord puis en VARCHAR (en passant "1" pour le e argument de CONVERT () pour spécifier le "style" du format de sortie), par exemple:

   select CONVERT(VARCHAR, CONVERT(MONEY, 123456789.75), 1)    --> 123,456,789.75
3
Eddie Kumar

Pas sûr que cela fonctionne dans tsql, mais certaines plates-formes ont to_char():

test=#select to_char(131213211653.78, '9,999,999,999,999.99');
        to_char        
-----------------------
    131,213,211,653.78
test=# select to_char(131213211653.78, '9G999G999G999G999D99');
        to_char        
-----------------------
    131,213,211,653.78
test=# select to_char(485, 'RN');
     to_char     
-----------------
         CDLXXXV

Comme l'exemple le suggère, la longueur du format doit correspondre à celle du nombre pour de meilleurs résultats, vous pouvez donc vouloir l'encapsuler dans une fonction (par exemple, number_format ()) si nécessaire.


La conversion en argent fonctionne également, comme le soulignent les autres répondants.

test=# select substring(cast(cast(131213211653.78 as money) as varchar) from 2);
     substring      
--------------------
 131,213,211,653.78
3
Denis de Bernardy

J'ai examiné plusieurs des options. Voici mes deux favoris, car j'avais besoin d'arrondir la valeur.

,DataSizeKB = replace(convert(varchar,Cast(Round(SUM(BigNbr / 0.128),0)as money),1), '.00','')
,DataSizeKB2   = format(Round(SUM(BigNbr / 0.128),0),'##,##0')
-----------------
--- below if the full script where I left DataSizeKB in both methods -----------
--- enjoy --------- 
--- Hank Freeman : [email protected] 
-----------------------------------
--- Scritp to get rowcounts and Memory size of index and Primary Keys
   SELECT
   FileGroupName = DS.name
   ,FileGroupType =
      CASE DS.[type]
        WHEN 'FG' THEN 'Filegroup'
        WHEN 'FD' THEN 'Filestream'
        WHEN 'FX' THEN 'Memory-optimized'
        WHEN 'PS' THEN 'Partition Scheme'
        ELSE 'Unknown'
      END
   ,SchemaName = SCH.name
   ,TableName = OBJ.name
   ,IndexType =
      CASE IDX.[type]
        WHEN 0 THEN 'Heap'
        WHEN 1 THEN 'Clustered'
        WHEN 2 THEN 'Nonclustered'
        WHEN 3 THEN 'XML'
        WHEN 4 THEN 'Spatial'
        WHEN 5 THEN 'Clustered columnstore'
        WHEN 6 THEN 'Nonclustered columnstore'
        WHEN 7 THEN 'Nonclustered hash'
      END
   ,IndexName = IDX.name
   ,RowCounts = replace(convert(varchar,Cast(p.rows as money),1), '.00','')  --- MUST show for all types when no Primary key
   --,( Case WHEN IDX.[type] IN (2,6,7) then 0  else  p.rows  end )as Rowcounts_T
   ,AllocationDesc = AU.type_desc
/*
   ,RowCounts = p.rows  --- MUST show for all types when no Primary key
   ,TotalSizeKB2  = Cast(Round(SUM(AU.total_pages / 0.128),0)as int) -- 128 pages per megabyte
   ,UsedSizeKB    = Cast(Round(SUM(AU.used_pages / 0.128),0)as int) 
   ,DataSizeKB    = Cast(Round(SUM(AU.data_pages / 0.128),0)as int)
    --replace(convert(varchar,cast(1234567 as money),1), '.00','')
*/
   ,TotalSizeKB   = replace(convert(varchar,Cast(Round(SUM(AU.total_pages / 0.128),0)as money),1), '.00','') -- 128 pages per megabyte
   ,UsedSizeKB    = replace(convert(varchar,Cast(Round(SUM(AU.used_pages / 0.128),0)as money),1), '.00','') 
   ,DataSizeKB    = replace(convert(varchar,Cast(Round(SUM(AU.data_pages / 0.128),0)as money),1), '.00','')
   ,DataSizeKB2   = format(Round(SUM(AU.data_pages / 0.128),0),'##,##0')
   ,DataSizeKB3   = format(SUM(AU.data_pages / 0.128),'##,##0')
   --SELECT Format(1234567.8, '##,##0.00')
   ---
   ,is_default    = CONVERT(INT,DS.is_default)
   ,is_read_only = CONVERT(INT,DS.is_read_only)
  FROM
   sys.filegroups DS -- you could also use sys.data_spaces
    LEFT JOIN sys.allocation_units AU ON DS.data_space_id = AU.data_space_id
    LEFT JOIN sys.partitions PA
      ON (AU.[type] IN (1,3) AND
          AU.container_id = PA.hobt_id) OR
         (AU.[type] = 2 AND
          AU.container_id = PA.[partition_id])
    LEFT JOIN sys.objects OBJ ON PA.[object_id] = OBJ.[object_id]
    LEFT JOIN sys.schemas SCH ON OBJ.[schema_id] = SCH.[schema_id]
    LEFT JOIN sys.indexes IDX
      ON PA.[object_id] = IDX.[object_id] AND
         PA.index_id = IDX.index_id
    -----
    INNER JOIN 
      sys.partitions p ON obj.object_id = p.OBJECT_ID AND IDX.index_id = p.index_id
  WHERE
    OBJ.type_desc = 'USER_TABLE' -- only include user tables
    OR
    DS.[type] = 'FD' -- or the filestream filegroup
  GROUP BY
    DS.name ,SCH.name ,OBJ.name ,IDX.[type] ,IDX.name ,DS.[type]  ,DS.is_default   ,DS.is_read_only -- discard different allocation units
   ,p.rows  ,AU.type_desc  --- 
  ORDER BY
    DS.name ,SCH.name ,OBJ.name ,IDX.name
   ---
   ;
0
Hank Freeman

Vous ne devriez vraiment pas faire cela en SQL - vous devriez plutôt le formater dans le middleware. Mais je reconnais que parfois il y a un cas Edge qui exige que l'on fasse une telle chose.

Il semble que cela pourrait avoir votre réponse:

Comment formater un nombre avec des virgules en T-SQL?

0
djdanlib