Tipo de datos apropiado para mantener valores porcentuales?


¿Cuál es el mejor tipo de datos para mantener valores porcentuales que van desde 0.00% hasta 100.00%?

Author: Jeff, 2010-05-04

5 answers

Suponiendo dos decimales en sus porcentajes, el tipo de datos que utiliza depende de cómo planea almacenar sus porcentajes. Si va a almacenar su equivalente fraccional (por ejemplo, 100.00% almacenado como 1.0000), almacenaría los datos en un tipo de datos decimal(5,4) con una restricción CHECK que garantiza que los valores nunca excedan 1.0000 (suponiendo que es el límite) y nunca vayan por debajo de 0 (suponiendo que es el piso). Si va a almacenar su valor facial (por ejemplo, 100.00% se almacena como 100.00), entonces usted debe usar decimal(5,2) con una restricción apropiada CHECK. Combinado con un buen nombre de columna, deja claro a otros desarrolladores qué son los datos y cómo se almacenan los datos en la columna.

 93
Author: Thomas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-15 21:01:29
  • Mantener como un decimal.
  • Agregue restricciones de verificación si desea limitar el rango (por ejemplo, entre 0 y 100%; en algunos casos puede haber razones válidas para ir más allá del 100% o potencialmente incluso en los negativos).
  • Tratar el valor 1 como 100%, 0.5 como 50%, etc. Esto permitirá que cualquier operación matemática funcione como se espera (es decir, en lugar de usar el valor 100 como 100%).
  • Modifíquese la precisión y la escala según sea necesario (estos son los dos valores entre paréntesis columnName decimal(precision, scale). Precisión dice la número total de dígitos que se pueden mantener en el número, la escala dice cuántos de ellos están después del lugar decimal, por lo que decimal(3,2) es un número que se puede representar como #.##; decimal(5,3) sería ##.###.
  • decimal y numeric son esencialmente la misma cosa. Sin embargo, decimal es compatible con ANSI, así que siempre use eso a menos que se le indique lo contrario (por ejemplo, por los estándares de codificación de su empresa).

Escenarios de ejemplo

  • Para su caso (0.00% a 100.00%) usted querría decimal(5,4).
  • Para el caso más común (0% a 100%) que querrías decimal(3,2).
  • En ambas de las anteriores, las restricciones de verificación serían las mismas

Ejemplo:

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

Lectura adicional:

 16
Author: JohnLBevan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:50

Si 2 decimales es su nivel de precisión, entonces un "smallint" manejaría esto en el espacio más pequeño (2 bytes). Almacena el porcentaje multiplicado por 100.

EDITAR: El tipo decimal es probablemente una mejor coincidencia. Entonces no necesita escalar manualmente. Toma 5 bytes por valor.

 2
Author: mdma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-04 01:54:01

Estoy de acuerdo con Thomas y elegiría la solución DECIMAL(5,4) al menos para aplicaciones WPF.

Eche un vistazo a la cadena de formato numérico MSDN para saber por qué : http://msdn.microsoft.com/en-us/library/dwhawy9k#PFormatString

El especificador de formato percent ("P") multiplica un número por 100 y lo convierte en una cadena que representa un porcentaje.

Entonces usted podría usar esto en su código XAML:

DataFormatString="{}{0:P}"
 1
Author: pjehan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-05 08:48:59

Utilice numérica(n,n) donde n tiene suficiente resolución para redondear a 1.00. Por ejemplo:

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

select convert(money, @discount * @quantity)
 0
Author: user2202942,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-29 20:56:33