PRB: Perdita di precisione può verificarsi quando si utilizza SUM o AVG funzioni in una formula con divisione

Il presente articolo è stato tradotto tramite il software di traduzione automatica di Microsoft e non da una persona. Microsoft offre sia articoli tradotti da persone fisiche sia articoli tradotti automaticamente da un software, in modo da rendere disponibili tutti gli articoli presenti nella nostra Knowledge Base nella lingua madre dell’utente. Tuttavia, un articolo tradotto in modo automatico non è sempre perfetto. Potrebbe contenere errori di sintassi, di grammatica o di utilizzo dei vocaboli, più o meno allo stesso modo di come una persona straniera potrebbe commettere degli errori parlando una lingua che non è la sua. Microsoft non è responsabile di alcuna imprecisione, errore o danno cagionato da qualsiasi traduzione non corretta dei contenuti o dell’utilizzo degli stessi fatto dai propri clienti. Microsoft, inoltre, aggiorna frequentemente il software di traduzione automatica.

Clicca qui per visualizzare la versione originale in inglese dell’articolo: 281341
Questo articolo è stato archiviato. L’articolo, quindi, viene offerto “così come è” e non verrà più aggiornato.
Sintomi
Quando si utilizza la funzione di aggregazione SUM o AVG con divisione, il risultato perde precisione. Si verifica la perdita di precisione indipendentemente dall'utilizzo di un tipo di dati numeric o decimal.
Cause
Questo comportamento è a causa di natura dei tipi di dati decimal e numeric e il troncamento che si verifica come risultato della precisione e i valori di scala. Secondo documentazione in linea di SQL Server, il risultato di sum(numeric(p,s)) è numeric(38,s). Nel caso precedente, sum(amount) è numeric(38,9). Quando si dispone di un'espressione di numeric(38,9) / numeric(15,9); in teoria, il risultato è numeric(63,25). Poiché la precisione massima è 38, il risultato viene troncato a (38,6).
Workaround
Per aggirare il problema, utilizzare uno di questi metodi:
  • Utilizzare un numerico come divisore. Ad esempio:

    DECLARE @Quantity numeric(15,9)SET @Quantity = 3SELECT Round(CAST(Sum(t1.Amount) AS numeric(15,9))/@Quantity, 9) As CostFROM t1					
  • Memorizzare prima la somma in una variabile e utilizzare la variabile nella formula. Ad esempio:

    declare @quantity numeric (15,9)set @quantity = 3declare @sum numeric (15,9)set @sum= (select sum(amount) from t1)select @sum/@quantity as cost					
  • Inserire un valore esplicito in un denominatore. Ad esempio:
    select sum(Amount)/3 from t1					
Informazioni
Per riprodurre il problema, eseguirla la seguente query da Query Analyzer:
CREATE TABLE t1 (    Amount    numeric(15,9)    )GOINSERT INTO t1( Amount ) VALUES (0.7)INSERT INTO t1( Amount ) VALUES (1.3)SELECT Amount FROM t1/* result (correct, scale = 9)Amount      ----------------- .7000000001.300000000DECLARE @Quantity numeric(15,9)SET @Quantity = 3    SELECT t1.Amount / @Quantity As CostFROM t1				
Again, la scala e precisione siano corretti nel risultato.

Tuttavia, se si utilizza questo codice
DECLARE @Quantity numeric(15,9)<BR/>SET @Quantity = 3SELECT Sum(t1.Amount)/@Quantity As Cost<BR/>FROM t1				
il risultato è.666666.

La perdita di precisione non si verifica se si fornisce un valore esplicito nel denominatore. Perdita di precisione non si verifica se si inserisce il valore della somma:
select sum(Amount)/3 from t1GOselect 2.0000000/@quantity				
senza perdita di precisione si verifica se si memorizzano SUM(amount) in una variabile e si utilizza quindi la variabile. La perdita di precisione si verifica solo quando si utilizza la SUM o AVG parola chiave aggregata in una formula matematica con divisione.
declare @quantity numeric (15,9)set @quantity = 3declare @sum numeric (15,9)set @sum= (select sum(amount) from t1)select @sum/@quantity as cost				
divisione di troncamento Somma media di precisione

Avviso: questo articolo è stato tradotto automaticamente

Proprietà

ID articolo: 281341 - Ultima revisione: 12/05/2015 23:03:35 - Revisione: 3.2

Microsoft SQL Server 7.0 Standard Edition, Microsoft SQL Server 2000 Standard Edition

  • kbnosurvey kbarchive kbmt kbprb KB281341 KbMtit
Feedback
ERROR: at System.Diagnostics.Process.Kill() at Microsoft.Support.SEOInfrastructureService.PhantomJS.PhantomJSRunner.WaitForExit(Process process, Int32 waitTime, StringBuilder dataBuilder, Boolean isTotalProcessTimeout)