Geeigneter Datentyp zum Halten von Prozentwerten?

Antworten:

131

Angenommen, Ihre Prozentsätze enthalten zwei Dezimalstellen. Der verwendete Datentyp hängt davon ab, wie Sie Ihre Prozentsätze speichern möchten. Wenn Sie ihr gebrochenes Äquivalent speichern möchten (z. B. 100,00% als 1,0000 gespeichert), würde ich die Daten in einem decimal(5,4)Datentyp mit einer CHECKEinschränkung speichern, die sicherstellt, dass die Werte niemals 1,0000 überschreiten (vorausgesetzt, dies ist die Obergrenze) und niemals unter 0 fallen (vorausgesetzt, das ist der Boden). Wenn Sie ihren Nennwert speichern möchten (z. B. 100,00% werden als 100,00 gespeichert), sollten Sie ihn decimal(5,2)mit einer geeigneten CHECKEinschränkung verwenden. In Kombination mit einem guten Spaltennamen wird anderen Entwicklern klar, was die Daten sind und wie die Daten in der Spalte gespeichert werden.

Thomas
quelle
12
Sollte es nicht sein, decimal(5,2)dass 2 die Anzahl der Stellen nach dem Dezimaltrennzeichen bezeichnet?
Boris Callens
2
@ BorisCallens - Ich kann nicht glauben, dass ich das all die Jahre verpasst habe. Ja, das ist ein Tippfehler. decimal(5,2)ist das, was mit einer Prüfbedingung erfasst werden sollte.
Thomas
4
Ich gehe davon aus, dass dies ursprünglich der Fall war decimal(5,4)und decimal(5,2)nach dem obigen Kommentar geändert wurde ... Ich denke, dies decimal(5,4)wäre die bessere Definition - dh Sie möchten 0 bis 1 mit 2 Dezimalstellen speichern, nicht 0 bis 100. Der Grund, warum ein Prozentsatz angegeben ist, liegt außerhalb von 100; 100% ist also 100/100, was 1 ist. In den meisten Fällen ist es sinnvoller, dies auf diese Weise zu tun (z. B. 100% * 100% = 100%nicht 10000%; 1 * 1 = 1).
JohnLBevan
4
@JohnLBevan - Es hängt davon ab, wie sie gespeichert werden. Wenn die Werte wie angezeigt gespeichert werden sollen (z. B. 100.00), müssen Sie decimal(5,2). Wenn die Werte als Brüche gespeichert werden sollen (z. B. 1.0000), müssen Sie decimal(5,4). Wird den Beitrag aktualisieren.
Thomas
Kann jemand erklären, warum Sie 4 Dezimalstellen benötigen? Kannst du nicht 2 benutzen? Wie .91 === 91% oder 1.00 === 100%. Ich implementiere dies jetzt und habe mich über den Gewinn mit 4 Plätzen gewundert. So etwas wie Pct decimal (10, 2) CHECK (Pct> =. 01 AND Pct <= 1). Danke im Voraus.
MH
31
  • Halten Sie als decimal.
  • Fügen Sie Prüfeinschränkungen hinzu, wenn Sie den Bereich einschränken möchten (z. B. zwischen 0 und 100%; in einigen Fällen kann es triftige Gründe geben, über 100% oder möglicherweise sogar in die Negative zu gehen).
  • Behandeln Sie Wert 1 als 100%, 0,5 als 50% usw. Dadurch können alle mathematischen Operationen wie erwartet funktionieren (dh im Gegensatz zur Verwendung von Wert 100 als 100%).
  • Ändern Sie die Genauigkeit und Skalierung nach Bedarf (dies sind die beiden Werte in Klammern columnName decimal(precision, scale). Die Genauigkeit gibt die Gesamtzahl der Ziffern an, die in der Zahl enthalten sein können. Die Skalierung gibt an, wie viele davon nach der Dezimalstelle stehen, also decimal(3,2)eine Zahl, die dargestellt werden kann wie #.##; decimal(5,3)wäre##.### .
  • decimalund numericsind im Wesentlichen das gleiche. Ist decimaljedoch ANSI-konform, verwenden Sie dies immer, sofern nicht anders angegeben (z. B. durch die Codierungsstandards Ihres Unternehmens).

Beispielszenarien

  • Für Ihren Fall (0,00% bis 100,00%) möchten Sie decimal(5,4).
  • Für den häufigsten Fall (0% bis 100%) möchten Sie decimal(3,2).
  • In beiden oben genannten Fällen wären die Überprüfungsbeschränkungen gleich

Beispiel:

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

Weiterführende Literatur:

JohnLBevan
quelle
4

Ich stimme Thomas zu und würde die DECIMAL (5,4) -Lösung zumindest für WPF-Anwendungen wählen.

In der MSDN Numeric Format String erfahren Sie, warum: http://msdn.microsoft.com/en-us/library/dwhawy9k#PFormatString

Der Prozentbezeichner ("P") multipliziert eine Zahl mit 100 und konvertiert sie in eine Zeichenfolge, die einen Prozentsatz darstellt.

Dann können Sie dies in Ihrem XAML-Code verwenden:

DataFormatString="{}{0:P}"
pjehan
quelle
2

Wenn 2 Dezimalstellen Ihre Genauigkeit sind, würde ein "smallint" dies auf kleinstem Raum (2 Bytes) verarbeiten. Sie speichern den Prozentsatz multipliziert mit 100.

EDIT: Der Dezimaltyp passt wahrscheinlich besser zusammen. Dann müssen Sie nicht manuell skalieren. Es dauert 5 Bytes pro Wert.

mdma
quelle
Microsoft hat so viele seiner Links
unterbrochen
0

Verwenden Sie numerisch (n, n), wobei n eine ausreichende Auflösung hat, um auf 1,00 zu runden. Zum Beispiel:

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

select convert(money, @discount * @quantity)
user2202942
quelle
3
Diese Frage hat eine ziemlich hoch bewertete akzeptierte Antwort von vor über drei Jahren. Wenn Sie nach alten Fragen suchen, die Sie beantworten können, lesen
valverij