web-dev-qa-db-ja.com

「COUNT」は重複をカウントしないと教授が教えてくれました

大学で、私の教授は今年、このSQLステートメントについて次のように教えてくれました。

SELECT COUNT(length) FROM product

戻ります 2次のデータセットを使用:

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

彼女は、COUNTは重複をカウントしないと言ってそれを正当化しました。

私は教授に間違いを犯したと思ったと言った。一部のDBMSは重複をカウントする場合としない場合があると彼女は答えました。

多くのDBMSを試した後、私はこのような振る舞いを持つDBMSを見つけたことはありません。

このDBMSは存在しますか?

教授がこの行動を教える理由はありますか?また、他のDBMSの動作が異なる可能性があることについても触れていませんか?


参考までに、コースのサポートが利用可能です ここ(フランス語) 。関連するスライドは、10ページの左下隅にあります。

40
Jules Lamur

COUNTは、私が知っているすべてのDBMSで重複をカウントしますが、.

教授がこの行動を教える理由はありますか

はい、理由があります。元のリレーショナル理論では(これはすべての最新のリレーショナルDBMSの基礎となる)relationsetこの単語の数学的な意味で。つまり、「テーブル」だけでなく、すべての遷移関係を含め、どの関係にも重複を含めることはできません。

この原則に従うと、SELECT length FROM productにはすでに2行しか含まれていないため、対応するCOUNT2ではなく3を返します。


たとえば、 Rel DBMSでは、質問で指定された関係と Tutorial D 構文を使用します。

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

与える:

Rel result

37
Vadim Pushtaev

あなたの教授は間違いをしたか、あなたは彼女が言ったことを誤解しました。リレーショナルDBMSのコンテキストでは、さまざまなベンダーによって実装されているように、集計関数COUNT(<expression>)は、結果セット(またはグループ)内の_<expression>_のNULL以外の値の数を返します。

COUNT(*)の特別なケースがあり、結果セットまたはグループ内のrowsの数を返します。値の数ではありません。これは、COUNT(<constant expression>)などのCOUNT(1)と同等です。

多くのデータベースはCOUNT(DISTINCT <expression>)をサポートしています。これはwillが_<expression>_の一意の値の数を返します。

47
mustaccio

教授がSQLについて話している場合、ステートメントは間違っています。 COUNT(x)は、x _IS NOT NULL_の重複を含む行の数を返します。 COUNT(*) or COUNT([constant])は、すべての列がNULLであっても、行をカウントする特別なケースです。ただし、COUNT(distinct x)を指定しない限り、重複は常にカウントされます。例:

_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です。

補足として、NULLは直感的でない動作をもたらします。例として:

_SELECT SUM(x) + SUM(y),  SUM(x + y) FROM T
4, 2
_

つまり:

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

たとえば、本 データベース、タイプ、およびリレーショナルモデル:第3の宣言 によって記述されているリレーショナルシステムについて話している場合、CJ日付とヒューダーウェンは正しいでしょう。ステートメント。

次の関係があるとします。

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

に対応:

_COUNT(STUDENTS.project(['Name']))
_

つまり.

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

これは2を返します。

13
Lennart

これは、MS SQL Serverでの動作方法です。

COUNT(*)は、グループ内のアイテムの数を返します。これには、NULL値と重複が含まれます。

COUNT(ALL式)は、グループ内の各行の式を評価し、null以外の値の数を返します。

COUNT(DISTINCT式)は、グループ内の各行の式を評価し、nullでない一意の値の数を返します。

3
Daniel Björk

テーブルがこのようになっていたら、

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

nullはカウントされないため、クエリは少なくともOracle DBでは2を返すことが期待できます。ただし、重複は問題なくカウントされます。

1
Terje