Cómputos con valores numéricos - Amazon Redshift

Cómputos con valores numéricos

En este contexto, cómputo se refiere a operaciones matemáticas binarias: suma, resta, multiplicación y división. En esta sección se describen los tipos devueltos previstos para estas operaciones, así como la fórmula específica que se aplica para determinar la precisión y la escala cuando hay tipos de datos DECIMAL involucrados.

Cuando se computan los valores numéricos durante el procesamiento de consultas, puede encontrar casos donde el cómputo no es posible y la consulta devuelve un error de desbordamiento numérico. También puede encontrar casos donde una escala de valores computados varía o es inesperada. Para algunas operaciones, puede usar conversiones explícitas (tipo de promoción) o parámetros de configuración de Amazon Redshift para solucionar estos problemas.

Para obtener más información acerca de los resultados de cálculo similares con funciones SQL, consulte Funciones de agregación.

Tipos devueltos para cómputos

Dado el conjunto de tipos de datos numéricos admitidos en Amazon Redshift, en la siguiente tabla, se muestran los tipos devueltos previstos para las operaciones de suma, resta, multiplicación y división. La primera columna del lado izquierdo de la tabla representa el primer operando del cálculo, y la fila superior representa el segundo operando.

INT2 INT4 INT8 DECIMAL FLOAT4 FLOAT8
INT2 INT2 INT4 INT8 DECIMAL FLOAT8 FLOAT8
INT4 INT4 INT4 INT8 DECIMAL FLOAT8 FLOAT8
INT8 INT8 INT8 INT8 DECIMAL FLOAT8 FLOAT8
DECIMAL DECIMAL DECIMAL DECIMAL DECIMAL FLOAT8 FLOAT8
FLOAT4 FLOAT8 FLOAT8 FLOAT8 FLOAT8 FLOAT4 FLOAT8
FLOAT8 FLOAT8 FLOAT8 FLOAT8 FLOAT8 FLOAT8 FLOAT8

Precisión y escala de resultados DECIMAL computados

En la siguiente tabla se resumen las reglas para computar la precisión y la escala resultantes cuando las operaciones matemáticas devuelven resultados DECIMAL. En esta tabla, p1 y s1 representan la precisión y escala del primer operando en un cálculo, y p2 y s2 representan la precisión y escala del segundo operando. (Independientemente de estos cálculos, la precisión de resultados máxima es 38 y la escala de resultados máxima es 38).

Operación Precisión y escala del resultado
+ o bien - Escalado = max(s1,s2)

Precisión = max(p1-s1,p2-s2)+1+scale

* Escalado = s1+s2

Precisión = p1+p2+1

/ Escalado = max(4,s1+p2-s2+1)

Precisión = p1-s1+ s2+scale

Por ejemplo, las columnas PRICEPAID y COMMISSION de la tabla SALES son columnas DECIMAL(8,2). Si divide PRICEPAID por COMMISSION (o viceversa), la fórmula se aplica de la siguiente manera:

Precision = 8-2 + 2 + max(4,2+8-2+1) = 6 + 2 + 9 = 17 Scale = max(4,2+8-2+1) = 9 Result = DECIMAL(17,9)

El siguiente cálculo es la regla general para computar la precisión y la escala resultantes para operaciones realizadas en valores DECIMAL con operadores como UNION, INTERSECT o EXCEPT, o funciones como COALESCE y DECODE:

Scale = max(s1,s2) Precision = min(max(p1-s1,p2-s2)+scale,19)

Por ejemplo, una tabla DEC1 con una columna DECIMAL(7,2) se combina con una tabla DEC2 con una columna DECIMAL(15,3) para crear una tabla DEC3. En el esquema de DEC3 se muestra que la columna se convierte en una columna NUMERIC(15,3).

create table dec3 as select * from dec1 union select * from dec2;

Resultado

select "column", type, encoding, distkey, sortkey from pg_table_def where tablename = 'dec3'; column | type | encoding | distkey | sortkey -------+---------------+----------+---------+--------- c1 | numeric(15,3) | none | f | 0

En el ejemplo anterior, la fórmula se aplica de la siguiente manera:

Precision = min(max(7-2,15-3) + max(2,3), 19) = 12 + 3 = 15 Scale = max(2,3) = 3 Result = DECIMAL(15,3)

Notas sobre las operaciones de división

Para las operaciones de división, dividir las condiciones por cero devuelve errores.

El límite de escala de 100 se aplica después de que se calculan la precisión y la escala. Si la escala resultante calculada es superior a 100, los resultados de la división están escalados de la siguiente manera:

  • Precisión = precision - (scale - max_scale)

  • Escalado = max_scale

Si la precisión calculada es superior a la precisión máxima (38), la precisión se reduce a 38 y la escala se convierte en el resultado de: max((38 + scale - precision), min(4, 100))

Condiciones de desbordamiento

Se revisa el desbordamiento para todos los cómputos numéricos. Los datos DECIMAL con una precisión de 19 o menos se almacenan como enteros de 64 bits. Los datos DECIMAL con una precisión superior a 19 se almacenan como enteros de 128 bits. La precisión máxima para todos los valores DECIMAL es 38 y la escala máxima es 37. Los errores de desbordamiento ocurren cuando un valor supera estos límites, que se aplican en los conjuntos de resultados intermedios y finales:

  • Las formas explícitas generan errores de desbordamiento de tiempo de ejecución cuando los valores de datos específicos no se ajustan a la precisión o escala solicitada y especificada por la función de formación. Por ejemplo, no puede formar todos los valores de la columna PRICEPAID en la tabla SALES (una columna DECIMAL(38,2)) y devolver un resultado DECIMAL(7,3):

    select pricepaid::decimal(7,3) from sales; ERROR: Numeric data overflow (result precision)

    Este error se produce porque algunos de los valores más grandes de la columna PRICEPAID no se pueden formar.

  • Las operaciones de multiplicación producen resultados en los que la escala de resultados es la suma de la escala de cada operando. Si ambos operandos tienen una escala de 4, por ejemplo, la escala resultante es 8, dejando solo 10 dígitos para el lado izquierdo del punto decimal. Por lo tanto, es relativamente fácil encontrarse con condiciones de desbordamiento cuando multiplica dos números grandes que tienen escalas significativas.

    El siguiente ejemplo produce un error de desbordamiento.

    SELECT CAST(1 AS DECIMAL(38, 20)) * CAST(10 AS DECIMAL(38, 20)); ERROR: 128 bit numeric data overflow (multiplication)

    Puede evitar el error de desbordamiento mediante la división en lugar de la multiplicación. Utilice el siguiente ejemplo para dividir por 1 dividido por el divisor original.

    SELECT CAST(1 AS DECIMAL(38, 20)) / (1 / CAST(10 AS DECIMAL(38, 20))); +----------+ | ?column? | +----------+ | 10 | +----------+

Cálculos numéricos con tipos INTEGER y DECIMAL

Cuando uno de los operandos en un cálculo tiene un tipo de datos INTEGER y el otro operando es DECIMAL, el operando INTEGER se forma implícitamente como un DECIMAL:

  • INT2 (SMALLINT) se forma como DECIMAL(5,0)

  • INT4 (INTEGER) se forma como DECIMAL(10,0)

  • INT8 (BIGINT) se forma como DECIMAL(19,0)

Por ejemplo, si multiplica SALES.COMMISSION, una columna DECIMAL(8,2), y SALES.QTYSOLD, una columna SMALLINT, este cálculo se forma de la siguiente manera:

DECIMAL(8,2) * DECIMAL(5,0)