Meu professor me ensinou que "COUNT" não conta duplicatas

40

Na universidade, meu professor me ensinou este ano que esta instrução SQL:

SELECT COUNT(length) FROM product

retornará 2com o seguinte conjunto de dados:

|   product         |
|id | length | code |
|-------------------|
| 1 |    11  | X00  |
| 2 |    11  | C02  |
| 3 |    40  | A31  |

Ela justificou dizendo que COUNTnão conta duplicatas.

Eu disse ao meu professor que achava que ela havia cometido um erro. Ela me respondeu que alguns DBMS podem ou não contar duplicados.

Depois de experimentar muitos DBMS, nunca encontrei um que tivesse esse comportamento.

Este DBMS existe?

Existe alguma razão para um professor ensinar esse comportamento? E sem mencionar que outros DBMS podem se comportar de maneira diferente?


Para sua informação, o suporte ao curso está disponível aqui (em francês) . O slide em questão está no canto inferior esquerdo na página 10.

Jules Lamur
fonte
11
Como os slides falam sobre o ANSi SQL, seu professor está errado, mesmo no padrão de 1992 (consulte a página 125 aqui contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt ) lista os vários comportamentos para contagem com e sem DISTINCT. Você pode querer visitar a biblioteca tonged uma versão atualizada (que inclui mais opções como ALL / OVER)
Eckes

Respostas:

38

COUNT conta duplicatas em todos os DBMS que eu conheço, mas.

Existe alguma razão para um professor ensinar esse comportamento

Sim, há uma razão. Na teoria relacional original (que subjaz a todos os SGBDs relacionais modernos), a relação é um conjunto no sentido matemático dessa palavra. Isso significa que nenhuma relação pode conter duplicatas, incluindo todas as relações de transição, não apenas suas "tabelas".

Seguindo esse princípio, você pode dizer que SELECT length FROM productjá contém apenas duas linhas, portanto COUNTretornos correspondentes 2, não 3.


Por exemplo, no DBMS de Rel , usando a relação fornecida na pergunta e na sintaxe do Tutorial D :

SUMMARIZE product {length} BY {}: {c := COUNT()}

dá:

Resultado Rel

Vadim Pushtaev
fonte
11
Como tivemos cursos de teoria relacional com esse professor ainda este ano, acho que essa é a resposta correta. Enfim, vou pedir mais informações ao meu professor.
Jules Lamur
2
O professor talvez estivesse falando sobre DBMSs em geral, não apenas sobre DBMSs SQL. Como mostra a edição, existem implementações do modelo relacional (por exemplo, Rel), onde COUNTse comporta de maneira diferente das implementações SQL.
precisa saber é o seguinte
47

Seu professor cometeu um erro ou você não entendeu o que ela disse. No contexto de DBMSes relacionais, conforme implementado por vários fornecedores, a função agregada COUNT(<expression>)retorna o número de valores não NULL <expression>no conjunto de resultados (ou em um grupo).

Há um caso especial de COUNT(*), que retorna o número de linhas no conjunto ou grupo de resultados, não o número de valores de nada. Isso é equivalente a COUNT(<constant expression>), como COUNT(1).

Muitos bancos de dados apoiar COUNT(DISTINCT <expression>), que irá retornar o número de valores exclusivos de <expression>.

mustaccio
fonte
13

Se o seu professor estiver falando sobre SQL, a afirmação está errada. COUNT(x)retornará o número de linhas em que x IS NOT NULLincluindo duplicatas. COUNT(*) or COUNT([constant])é um caso especial que contará as linhas, mesmo aquelas em que cada coluna está NULL. No entanto, duplicatas são sempre contadas, a menos que você especifique COUNT(distinct x). Exemplo:

with t(x,y) as ( values (null,null),(null,1),(1,null),(1,1) )

select count(*) from t
4

select count(1) from t
4

select count(distinct 1) from t
1

select count(x) from t
2

select count(distinct x) from t
1

COUNT(distinct *) AFAIK inválido.

Como uma observação lateral, o NULL apresenta um comportamento não intuitivo. Como um exemplo:

SELECT SUM(x) + SUM(y),  SUM(x + y) FROM T
4, 2

ou seja:

SUM(x)+SUM(y) <> SUM(x+y)

Se ele estiver falando de um sistema relacional, como descrito, por exemplo, no livro Bancos de dados, Tipos e Modelo Relacional: O Terceiro Manifesto, de CJ Date e Hugh Darwen - seria uma afirmação correta.

Diga que temos a relação:

STUDENTS = Relation(["StudentId", "Name"]
                    , [{"StudentId":'S1', "Name":'Anne'},
                       {"StudentId":'S2', "Name":'Anne'},
                       {"StudentId":'S3', "Name":'Cindy'},
                     ])
SELECT COUNT(NAME) FROM STUDENTS

corresponde a:

COUNT(STUDENTS.project(['Name']))

ie

COUNT( Relation(["Name"]
               , [{"Name":'Anne'},
                  {"Name":'Cindy'},
                ]) )

que retornaria 2 .

Lennart
fonte
3

É assim que funciona no MS SQL Server

COUNT (*) retorna o número de itens em um grupo. Isso inclui valores NULL e duplicatas.

COUNT (ALL expressão) avalia expressão para cada linha em um grupo e retorna o número de valores não nulos.

COUNT (expressão DISTINCT) avalia a expressão para cada linha em um grupo e retorna o número de valores únicos e não nulos.

Daniel Björk
fonte
1

Se a mesa estivesse assim,

|   product         |
|id | length | code |
|-------------------|
| 1 |    11  | X00  |
| 2 |    11  | C02  |
| 3 |  null  | A31  |

você pode esperar que a consulta retorne 2, pelo menos no banco de dados Oracle, pois os nulos não são contados. No entanto, duplicatas são contadas muito bem.

Terje
fonte
-7

talvez ela queira dizer em conjunto com o exclusivo, mas o Count COUNT DUPLICATES. Existem alguns professores que não sabem as coisas deles, não se preocupe, basta informar seus colegas de classe / amigos para que, quando eles passarem a um nível mais alto de vida e na vida real, eles não esqueçam, melhor ainda, enviar uma mensagem anônima ao seu professor pedindo que ela não compreenda algumas das funções sql e queira uma demonstração, peça à sua professora uma maneira de a turma sugerir o que inserir: incluir duplicatas (não possui dados grandes) e, quando ela usa a contagem de funções, você a recebe. Algumas pessoas vão buscá-lo. Além disso, quando ela disser outros bancos de dados, peça a seu amigo que pergunte quais, em seguida, faça um duplo laço com ela e diga que você tentou todos esses bancos de dados e eles não funcionam como ela disse e essa contagem pega duplicatas.

dasda
fonte
2
Não tenho certeza se pretendia antagonizar deliberadamente o professor. Com alguns, pode ser inteiramente adequado apenas encontrá-los pessoalmente e perguntar sobre isso, com o contra-exemplo pronto (apenas para mostrar que você tem um motivo para perguntar). Ainda assim, o básico da abordagem é válido; até o OP a direção específica a ser usada.
RDFozz