Type de données approprié pour conserver les valeurs en pourcentage?

Réponses:

132

En supposant deux décimales sur vos pourcentages, le type de données que vous utilisez dépend de la façon dont vous prévoyez de stocker vos pourcentages. Si vous envisagez de stocker leur équivalent fractionnaire (par exemple, 100,00% stocké en tant que 1,0000), je stockerais les données dans un decimal(5,4)type de données avec une CHECKcontrainte qui garantit que les valeurs ne dépassent jamais 1,0000 (en supposant que c'est le plafond) et ne descendent jamais en dessous de 0 (en supposant que c'est le sol). Si vous allez stocker leur valeur nominale (par exemple, 100,00% est stocké sous la forme 100,00), vous devez utiliser decimal(5,2)avec une CHECKcontrainte appropriée . Combiné avec un bon nom de colonne, il indique clairement aux autres développeurs quelles sont les données et comment les données sont stockées dans la colonne.

Thomas
la source
12
Ne devrait-il pas être decimal(5,2)là où 2 indique le nombre de chiffres après le séparateur décimal?
Boris Callens
2
@BorisCallens - Je ne peux pas croire que j'ai raté ça toutes ces années. Oui, c'est une faute de frappe. decimal(5,2)est ce qui doit être capturé avec une contrainte de vérification.
Thomas
4
Je suppose que cela avait à l'origine decimal(5,4)et a été changé decimal(5,2)après le commentaire ci-dessus ... Je pense que ce decimal(5,4)serait la meilleure définition - c'est-à-dire que vous voulez stocker 0 à 1 avec 2 décimales, pas 0 à 100. La raison étant un pourcentage est hors de 100; donc 100% est 100/100, ce qui équivaut à 1. Le faire de cette façon a plus de sens dans la plupart des cas (par exemple 100% * 100% = 100%, non 10000%; 1 * 1 = 1).
JohnLBevan
4
@JohnLBevan - Il dépense sur la façon dont ils sont stockés. Si les valeurs sont stockées telles qu'affichées (par exemple 100.00), vous en avez besoin decimal(5,2). Si les valeurs doivent être stockées sous forme de fractions (par exemple 1.0000), vous en avez besoin decimal(5,4). Mettra à jour le message.
Thomas
Quelqu'un peut-il expliquer pourquoi vous avez besoin de 4 décimales? Vous ne pouvez pas utiliser 2? Comme .91 === 91% ou 1.00 === 100%. Je l'implémente maintenant et je me demandais le gain avec 4 places. Quelque chose comme Pct decimal (10, 2) CHECK (Pct> =. 01 AND Pct <= 1). Merci d'avance.
MH
31
  • Tenez comme un decimal.
  • Ajoutez des contraintes de vérification si vous souhaitez limiter la plage (par exemple entre 0 et 100%; dans certains cas, il peut y avoir des raisons valables d'aller au-delà de 100% ou même potentiellement dans les négatifs).
  • Traitez la valeur 1 comme 100%, 0,5 comme 50%, etc. Cela permettra à toutes les opérations mathématiques de fonctionner comme prévu (c'est-à-dire au lieu d'utiliser la valeur 100 comme 100%).
  • Modifiez la précision et l'échelle selon vos besoins (ce sont les deux valeurs entre parenthèses columnName decimal(precision, scale). La précision indique le nombre total de chiffres pouvant être contenus dans le nombre, l'échelle indique le nombre de chiffres après la décimale, de même decimal(3,2)qu'un nombre qui peut être représenté comme #.##; decimal(5,3)serait ##.###.
  • decimalet numericsont essentiellement la même chose. Cependant, il decimalest conforme à la norme ANSI, alors utilisez-le toujours sauf indication contraire (par exemple, selon les normes de codage de votre entreprise).

Exemples de scénarios

  • Pour votre cas (0,00% à 100,00%) que vous voudriez decimal(5,4).
  • Pour le cas le plus courant (0% à 100%) que vous voudriez decimal(3,2).
  • Dans les deux cas ci-dessus, les contraintes de contrôle seraient les mêmes

Exemple:

if object_id('Demo') is null
create table Demo
    (
        Id bigint not null identity(1,1) constraint pk_Demo primary key
        , Name nvarchar(256) not null constraint uk_Demo unique 
        , SomePercentValue decimal(3,2) constraint chk_Demo_SomePercentValue check (SomePercentValue between 0 and 1)
        , SomePrecisionPercentValue decimal(5,2) constraint chk_Demo_SomePrecisionPercentValue check (SomePrecisionPercentValue between 0 and 1)
    )

Lectures complémentaires:

JohnLBevan
la source
4

Je suis d'accord avec Thomas et je choisirais la solution DECIMAL (5,4) au moins pour les applications WPF.

Jetez un œil à la chaîne de format numérique MSDN pour savoir pourquoi: http://msdn.microsoft.com/en-us/library/dwhawy9k#PFormatString

Le spécificateur de format pour cent ("P") multiplie un nombre par 100 et le convertit en une chaîne qui représente un pourcentage.

Ensuite, vous pourrez utiliser ceci dans votre code XAML:

DataFormatString="{}{0:P}"
pjehan
la source
2

Si 2 décimales est votre niveau de précision, alors un "smallint" traitera ceci dans le plus petit espace (2 octets). Vous stockez le pourcentage multiplié par 100.

EDIT: Le type décimal est probablement une meilleure correspondance. Ensuite, vous n'avez pas besoin de mettre à l'échelle manuellement. Il faut 5 octets par valeur.

mdma
la source
Microsoft a rompu tellement de ses liens .....
pcnate le
0

Utilisez numérique (n, n) où n a une résolution suffisante pour arrondir à 1,00. Par exemple:

declare @discount numeric(9,9)
    , @quantity int
select @discount = 0.999999999
    , @quantity = 10000

select convert(money, @discount * @quantity)
user2202942
la source
3
Cette question a une réponse acceptée assez élevée d'il y a plus de trois ans. Si vous recherchez d'anciennes questions auxquelles répondre, veuillez vous référer ici: stackoverflow.com/unanswered
valverij