Tipo di dati appropriato per contenere i valori percentuali?


Risposte:


132

Supponendo due cifre decimali sulle tue percentuali, il tipo di dati che usi dipende da come prevedi di memorizzare le tue percentuali. Se hai intenzione di memorizzare il loro equivalente frazionario (ad esempio 100,00% memorizzato come 1,0000), memorizzerei i dati in un decimal(5,4)tipo di dati con un CHECKvincolo che garantisce che i valori non superino mai 1,0000 (supponendo che sia il limite) e non vadano mai al di sotto di 0 (supponendo che sia il pavimento). Se si desidera memorizzare il loro valore nominale (ad esempio, 100,00% viene memorizzato come 100,00), è necessario utilizzarlo decimal(5,2)con un CHECKvincolo appropriato . Combinato con un buon nome di colonna, rende chiaro agli altri sviluppatori quali sono i dati e come i dati vengono memorizzati nella colonna.


12
Non dovrebbe essere decimal(5,2)dove 2 indica il numero di cifre dopo il separatore decimale?
Boris Callens

2
@ BorisCallens - Non posso credere di averlo perso in tutti questi anni. Sì, è un errore di battitura. decimal(5,2)è ciò che dovrebbe essere catturato con un vincolo di controllo.
Thomas

4
Presumo che questo originariamente fosse decimal(5,4)ed è stato modificato decimal(5,2)dopo il commento sopra ... Penso che decimal(5,4)sarebbe la definizione migliore - cioè si desidera memorizzare da 0 a 1 con 2 cifre decimali, non da 0 a 100. Il motivo per cui una percentuale è fuori 100; quindi 100% è 100/100 che è 1. Farlo in questo modo ha più senso per la maggior parte dei casi (ad esempio 100% * 100% = 100%, no 10000%; 1 * 1 = 1).
JohnLBevan

4
@JohnLBevan - Spende per come vengono archiviati. Se i valori vengono memorizzati come visualizzati (ad esempio 100.00), allora è necessario decimal(5,2). Se i valori devono essere memorizzati come frazioni (ad esempio 1.0000), allora è necessario decimal(5,4). Aggiornerò il post.
Thomas

Qualcuno può spiegare perché hai bisogno di 4 cifre decimali? Non puoi usarne 2? Come .91 === 91% o 1.00 === 100%. Lo sto implementando ora e mi chiedevo il guadagno con 4 posizioni. Qualcosa come Pct decimal (10, 2) CHECK (Pct> =. 01 AND Pct <= 1). Grazie in anticipo.
MH

31
  • Tieni come a decimal.
  • Aggiungi vincoli di controllo se vuoi limitare l'intervallo (ad esempio tra 0 e 100%; in alcuni casi potrebbero esserci validi motivi per andare oltre il 100% o potenzialmente anche per i negativi).
  • Tratta il valore 1 come 100%, 0,5 come 50% e così via. Ciò consentirà a qualsiasi operazione matematica di funzionare come previsto (ovvero invece di utilizzare il valore 100 come 100%).
  • Modificare la precisione e la scala come richiesto (questi sono i due valori tra parentesi columnName decimal(precision, scale). La precisione indica il numero totale di cifre che possono essere contenute nel numero, la scala indica quante di queste sono dopo la decimal(3,2)cifra decimale, quindi è un numero che può essere rappresentato come #.##, decimal(5,3)sarebbe ##.###.
  • decimale numericsono essenzialmente la stessa cosa. Tuttavia decimalè conforme ad ANSI, quindi usalo sempre se non diversamente specificato (ad esempio dagli standard di codifica della tua azienda).

Scenari di esempio

  • Per il tuo caso (dallo 0,00% al 100,00%) vorresti decimal(5,4).
  • Per il caso più comune (dallo 0% al 100%) vorresti decimal(3,2).
  • In entrambi i casi precedenti, i vincoli di controllo sarebbero gli stessi

Esempio:

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)
    )

Ulteriori letture:


4

Sono d'accordo con Thomas e sceglierei la soluzione DECIMAL (5,4) almeno per le applicazioni WPF.

Dai un'occhiata alla stringa del formato numerico MSDN per sapere perché: http://msdn.microsoft.com/en-us/library/dwhawy9k#PFormatString

L'identificatore di formato percentuale ("P") moltiplica un numero per 100 e lo converte in una stringa che rappresenta una percentuale.

Quindi potresti usarlo nel tuo codice XAML:

DataFormatString="{}{0:P}"

2

Se 2 cifre decimali sono il tuo livello di precisione, un "smallint" lo gestirà nello spazio più piccolo (2 byte). Memorizzi la percentuale moltiplicata per 100.

EDIT: il tipo decimale è probabilmente una corrispondenza migliore. Quindi non è necessario ridimensionare manualmente. Sono necessari 5 byte per valore.


Microsoft ha interrotto tanti dei suoi collegamenti .....
pcnate

0

Usa numerico (n, n) dove n ha una risoluzione sufficiente per arrotondare a 1,00. Per esempio:

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

select convert(money, @discount * @quantity)

3
Questa domanda ha una risposta accettata abbastanza alta da oltre tre anni fa. Se siete alla ricerca di vecchie domande a cui rispondere, si rimanda qui: stackoverflow.com/unanswered
valverij
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.