AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 25435
Accepted
Heinzi
Heinzi
Asked: 2012-10-05 08:49:05 +0800 CST2012-10-05 08:49:05 +0800 CST 2012-10-05 08:49:05 +0800 CST

Por que ANSI SQL define SUM (sem linhas) como NULL?

  • 772

O padrão ANSI SQL define (capítulo 6.5, especificação de função definida) o seguinte comportamento para funções agregadas em conjuntos de resultados vazios:

COUNT(...) = 0
AVG(...) = NULL
MIN(...) = NULL
MAX(...) = NULL
SUM(...) = NULL

Retornar NULL para AVG, MIN e MAX faz todo o sentido, já que a média, mínimo e máximo de um conjunto vazio é indefinido.

A última, porém, me incomoda: Matematicamente, a SOMA de um conjunto vazio está bem definida: 0. Usando 0, o elemento neutro da adição, como o caso base torna tudo consistente:

SUM({})        = 0    = 0
SUM({5})       = 5    = 0 + 5
SUM({5, 3})    = 8    = 0 + 5 + 3
SUM({5, NULL}) = NULL = 0 + 5 + NULL

Definir SUM({})como nullbasicamente torna "sem linhas" um caso especial que não se encaixa nos outros:

SUM({})     = NULL  = NULL
SUM({5})    = 5    != NULL + 5 (= NULL)
SUM({5, 3}) = 8    != NULL + 5 + 3 (= NULL)

Existe alguma vantagem óbvia da escolha que foi feita (SUM sendo NULL) que eu perdi?

null aggregate
  • 3 3 respostas
  • 7346 Views

3 respostas

  • Voted
  1. Best Answer
    Erwin Smout
    2012-10-05T14:12:15+08:002012-10-05T14:12:15+08:00

    Receio que o motivo seja simplesmente que as regras foram definidas de maneira ad hoc (como muitos outros "recursos" do padrão ISO SQL) em uma época em que as agregações SQL e sua conexão com a matemática eram menos compreendidas do que são agora (*).

    É apenas uma das muitas inconsistências na linguagem SQL. Eles tornam o idioma mais difícil de ensinar, mais difícil de aprender, mais difícil de entender, mais difícil de usar, mais difícil de fazer o que você quiser, mas é assim que as coisas são. As regras não podem ser alteradas "frio" e "simplesmente", por motivos óbvios de compatibilidade com versões anteriores (se o comitê ISO publicar uma versão final do padrão e os fornecedores decidirem implementar esse padrão, esses fornecedores não apreciarão muito se em uma versão subseqüente, as regras forem alteradas de forma que as implementações existentes (compatíveis) da versão anterior do padrão "não cumpram automaticamente" a nova versão ...)

    (*) Agora é melhor entender que as agregações sobre um conjunto vazio se comportam de maneira mais consistente se retornarem sistematicamente o valor de identidade (= o que você chama de 'elemento neutro') do operador binário subjacente em questão. Esse operador binário subjacente para COUNT e SUM é a adição e seu valor de identidade é zero. Para MIN e MAX, esse valor de identidade é o valor mais alto e mais baixo do tipo em questão, respectivamente, se os tipos em questão forem finitos. Casos como média, meios harmônicos, medianas, etc. são extremamente intrincados e exóticos a esse respeito.

    • 20
  2. Leigh Riffel
    2012-10-06T05:31:23+08:002012-10-06T05:31:23+08:00

    Em um sentido pragmático, o resultado existente de NULLé útil. Considere a seguinte tabela e declarações:

    C1 C2
    -- --
     1  3 
     2 -1 
     3 -2 
    
    SELECT SUM(C2) FROM T1 WHERE C1 > 9;
    
    SELECT SUM(C2) FROM T1 WHERE C1 < 9;
    

    A primeira instrução retorna NULL e a segunda retorna zero. Se um conjunto vazio retornasse zero SUM, precisaríamos de outro meio para distinguir uma verdadeira soma de zero de um conjunto vazio, talvez usando contagem. Se realmente quisermos zero para o conjunto vazio, um simples COALESCEfornecerá esse requisito.

    SELECT COALESCE(SUM(C2),0) FROM T1 WHERE C1 > 9;
    
    • 3
  3. TToni
    2012-10-06T02:53:03+08:002012-10-06T02:53:03+08:00

    A principal diferença que posso ver é em relação ao tipo de dados. COUNT tem um tipo de retorno bem definido: Um número inteiro. Todos os outros dependem do tipo de coluna/expressão que estão olhando. Seu tipo de retorno deve ser compatível com todos os membros do conjunto (pense em float, moeda, decimal, bcd, timespan, ...). Como não há conjunto, você não pode sugerir um tipo de retorno, portanto, NULL é sua melhor opção.

    Observação: na maioria dos casos, você pode sugerir um tipo de retorno do tipo de coluna que está vendo, mas pode fazer somas não apenas em colunas, mas em todos os tipos de coisas. Insinuar um tipo de retorno pode ser muito difícil, se não impossível, em certas circunstâncias, especialmente quando você pensa em possíveis expansões do padrão (tipos dinâmicos vêm à mente).

    • -1

relate perguntas

  • MAX para cada subconjunto

  • Como faço para particionar horizontalmente uma tabela de banco de dados oracle e devo?

  • Calculando a porcentagem de uma linha sobre a soma total

  • NULL ou NOT NULL por padrão?

  • Quando usar NULL e quando usar uma string vazia?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como ver a lista de bancos de dados no Oracle?

    • 8 respostas
  • Marko Smith

    Quão grande deve ser o mysql innodb_buffer_pool_size?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    restaurar a tabela do arquivo .frm e .ibd?

    • 10 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Como selecionar a primeira linha de cada grupo?

    • 6 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve