Talvez um dos recursos menos conhecidos do
FORMAT()
função no SQL Server é aquela que permite aplicar formatação condicional a um número. É mais um recurso .NET do que um recurso do SQL Server (ou T-SQL), mas o SQL Server/T-SQL oferece suporte a ele da mesma forma, permitindo que você aproveite ao máximo a capacidade de aplicar formatação condicional a números.
Tudo se resume à string de formato que você passa para o
FORMAT()
função. Você pode passar uma string de formato que especifica como o número deve ser formatado, dependendo se é positivo, negativo ou zero.
Só para ficar claro, não estou falando sobre formatar o número com cores ou fontes etc. Estou falando apenas sobre a formatação do número que você normalmente usaria o
FORMAT()
função para (como adicionar separadores de milhares, sinais de porcentagem, pontos decimais, etc). Além disso, essa formatação condicional é bastante limitada – apenas três condições podem ser testadas (positiva, negativa ou zero). No entanto, você também pode aplicar a mesma formatação a duas condições ao mesmo tempo, se necessário.
De qualquer forma, veja como usar o
FORMAT()
função para aplicar formatação condicional a um número no SQL Server. Apresentando ;
– O Separador de Seções
.NET define o ponto e vírgula (
;
) como um de seus especificadores de formato numérico personalizado, conhecido como separador de seção . O separador de seção é um especificador de formato condicional que define seções com strings de formato separadas para números positivos, negativos e zero. Isso permite que você aplique uma formatação diferente a um número, dependendo de seu valor ser positivo, negativo ou zero.
Uma string de formato numérico personalizado pode conter até três seções separadas por ponto e vírgula. Estes são os seguintes:
- Uma seção :Nenhuma formatação condicional se aplica neste caso. A string de formato se aplica a todos os valores. Nenhum separador de seção é necessário (porque há apenas uma seção). Sem dúvida, esta é a forma mais comum de string de formato.
- Duas seções :A primeira seção se aplica a valores positivos e zeros, e a segunda seção se aplica a valores negativos.
Se o número a ser formatado for negativo, mas se tornar zero após o arredondamento de acordo com o formato da segunda seção, o zero resultante será formatado de acordo com a primeira seção. - Três seções :a primeira seção se aplica a valores positivos, a segunda seção se aplica a valores negativos e a terceira seção se aplica a zeros.
A segunda seção pode ser deixada em branco (por não ter nada entre os pontos e vírgulas), caso em que a primeira seção se aplica a todos os valores diferentes de zero.
Se o número a ser formatado for diferente de zero, mas se tornar zero após o arredondamento de acordo com o formato na primeira ou na segunda seção, o zero resultante será formatado de acordo com a terceira seção.
Observe que os valores negativos sempre são exibidos sem um sinal de menos quando os separadores de seção são usados (embora haja exceções, como você verá mais adiante). Se você quiser que o valor final formatado tenha um sinal de menos, precisará incluir explicitamente o sinal de menos como parte da string de formato personalizado. Isso também se aplica a qualquer outra formatação preexistente associada a um número.
Exemplo 1 – Uma seção (sem formatação condicional)
Aqui está uma string de formato numérico típico que consiste em uma seção. Nenhum separador de seção é usado e, portanto, nenhuma formatação condicional se aplica .
Código:
SELECT FORMAT(123, '0 (Number)') Positive, FORMAT(-123, '0 (Number)') Negative, FORMAT(0, '0 (Number)') Zero;
Resultado:
+--------------+---------------+------------+ | Positive | Negative | Zero | |--------------+---------------+------------| | 123 (Number) | -123 (Number) | 0 (Number) | +--------------+---------------+------------+
Observe que o sinal de menos permanece intacto. Isso teria sido removido se tivéssemos usado separadores de seção.
Exemplo 2 – Duas seções (formatação condicional)
Aqui é onde a formatação condicional começa.
Neste exemplo, temos duas seções (separadas por um separador de seção). A seção à esquerda do separador se aplica apenas a valores positivos ou zero. A seção à direita só se aplica a valores negativos.
Código:
SELECT FORMAT(123, '0 (Positive or Zero); 0 (Negative)') Result;
Resultado:
+------------------------+ | Result | |------------------------| | 123 (Positive or Zero) | +------------------------+
Nesse caso o número foi positivo, então a primeira seção foi usada para formatá-lo.
Exemplo 3 – Duas seções (mesma string de formato, valores diferentes)
No próximo exemplo, a mesma string de formato é aplicada a valores diferentes (positivo, negativo e zero).
Código:
SELECT FORMAT(123, '0 (Positive or Zero); 0 (Negative)') Positive, FORMAT(-123, '0 (Positive or Zero); 0 (Negative)') Negative, FORMAT(0, '0 (Positive or Zero); 0 (Negative)') Zero;
Resultado:
+------------------------+-----------------+----------------------+ | Positive | Negative | Zero | |------------------------+-----------------+----------------------| | 123 (Positive or Zero) | 123 (Negative) | 0 (Positive or Zero) | +------------------------+-----------------+----------------------+
Portanto, este exemplo demonstra o verdadeiro benefício dos separadores de seção – que podemos obter um resultado diferente dependendo do valor.
Exemplo 4 – Duas seções com arredondamento
Ao usar duas seções, quaisquer valores negativos arredondados para zero são formatados na primeira string de formato.
Código:
SELECT FORMAT(0.1, '0 (Positive or Zero); 0 (Negative)') Positive, FORMAT(-0.1, '0 (Positive or Zero); 0 (Negative)') Negative;
Resultado:
+----------------------+----------------------+ | Positive | Negative | |----------------------+----------------------| | 0 (Positive or Zero) | 0 (Positive or Zero) | +----------------------+----------------------+
Exemplo 5 – Três seções (uso básico)
Aqui está um exemplo básico de especificação de três seções. Usamos dois separadores de seção para conseguir isso.
Código:
SELECT FORMAT(123, '0 (Positive); 0 (Negative); 0 (Zero)') Result;
Resultado:
+----------------+ | Result | |----------------| | 123 (Positive) | +----------------+
Nesse caso, o número era um valor positivo, portanto, foi formatado na primeira seção.
Exemplo 6 – Três seções (mesma string de formato, valores diferentes)
Este exemplo demonstra os vários resultados que poderíamos obter do exemplo anterior, dependendo do valor de entrada.
Aqui, a mesma string de formato é aplicada a valores diferentes. Também atribuo a string de formato a uma variável, mas isso é apenas para facilitar a leitura.
DECLARE @formatstring varchar(35); SET @formatstring = '0 (Positive); 0 (Negative); 0 (Zero)'; SELECT FORMAT(123, @formatstring) 'Positive', FORMAT(-123, @formatstring) 'Negative', FORMAT(0, @formatstring) 'Zero', FORMAT(0.123, @formatstring) 'Rounded to Zero';
Resultado:
+----------------+-----------------+----------+-------------------+ | Positive | Negative | Zero | Rounded to Zero | |----------------+-----------------+----------+-------------------| | 123 (Positive) | 123 (Negative) | 0 (Zero | 0 (Zero | +----------------+-----------------+----------+-------------------+
Exemplo 7 – Três Seções (incluindo uma vazia)
Se você deixar a segunda string de formato vazia, a primeira seção se aplicará a todos os valores diferentes de zero. Para deixá-lo vazio, basta não deixar nada entre os pontos e vírgulas.
Código:
SELECT FORMAT(123, '0 (Nonzero);; 0 (Zero)') 'Positive', FORMAT(-123, '0 (Nonzero);; 0 (Zero)') 'Negative', FORMAT(0, '0 (Nonzero);; 0 (Zero)') 'Zero', FORMAT(0.123, '0 (Nonzero);; 0 (Zero)') 'Rounded to Zero';
Resultado:
+---------------+----------------+-----------+-------------------+ | Positive | Negative | Zero | Rounded to Zero | |---------------+----------------+-----------+-------------------| | 123 (Nonzero) | -123 (Nonzero) | 0 (Zero) | 0 (Zero) | +---------------+----------------+-----------+-------------------+
Curiosamente, neste caso, o sinal de menos para o valor negativo é deixado intacto.
Exemplo 8 – O sinal de menos
Conforme mencionado, o separador de seção ignora qualquer formatação preexistente associada ao número. Isso inclui qualquer sinal de menos para valores negativos (embora o exemplo anterior pareça ser uma exceção a isso).
Se você quiser incluir o sinal de menos, precisará adicioná-lo explicitamente à sua string de formato. Exemplo abaixo.
Código:
SELECT FORMAT(-123, '0 (P); 0 (N); 0 (Z)') 'Without minus sign', FORMAT(-123, '0 (P); -0 (N); 0 (Z)') 'With minus sign';
Resultado:
+----------------------+-------------------+ | Without minus sign | With minus sign | |----------------------+-------------------| | 123 (N) | -123 (N) | +----------------------+-------------------+
Como apontado, o exemplo anterior parece ser uma exceção a isso, então algo a ter em mente. Aqui está o que acontece se eu adicionar um sinal de menos à string de formato para o valor negativo no exemplo anterior:
SELECT FORMAT(-123, '-0 (Nonzero);; 0 (Zero)') Result;
Resultado:
+-----------------+ | Result | |-----------------| | --123 (Nonzero) | +-----------------+