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
.
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
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!
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
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
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
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
---
;
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: