COUNT (SQL)
構文
COUNT(*)
COUNT(expression)
COUNT(DISTINCT expression)
COUNT(DISTINCT BY(column) expression)
COUNT(ALL expression)
COUNT( ... expression %FOREACH(column))
COUNT( ... expression ... %AFTERHAVING)
説明
COUNT は、テーブルまたは列の行数を返す集約関数です。COUNT は、BIGINT データ型を返します。行が存在しない場合、COUNT は 0 または NULL を返します (クエリによって異なります)。詳細は "カウントで行が返されない" を参照してください。
SELECT クエリで COUNT を使用して、クエリで参照しているテーブルの行数をカウントして結果セットに返します。テーブルまたはビューを参照するサブクエリや HAVING 節で COUNT を使用することもできます。WHERE 節では COUNT を使用できません。SELECT がサブクエリでない限り、JOIN の ON 節でも COUNT を使用できません。
-
COUNT(*) はテーブルまたはビューの行数を返します。COUNT(*) は、列の値が重複する行や NULL 値がある行なども含め、すべての行をカウントします。
以下のクエリは、Sample.Person にある行の合計数を返します。
SELECT COUNT(*) FROM Sample.Person
例 : テーブル行と列の値のカウント
-
COUNT(expression) は、テーブルの列名であるかデータの列に評価される式である expression に存在する値の数を返します。COUNT(expression) では NULL 値をカウントしません。
以下のクエリは、Sample.Person の Name 列にある NULL ではない値の数を返します。
SELECT COUNT(Name) AS TotalNames FROM Sample.Person
例を以下に示します。
-
COUNT(DISTINCT expression) は、DISTINCT 節を使用して expression 列にある個別 (固有) 値の個数を返します。ストリーム列では DISTINCT を使用できません。個別値としてカウントされる値は、列照合によって異なります。例えば、%SQLUPPER に既定の列照合を適用すると、文字の大文字と小文字が異なるだけの値は個別値としてカウントされません。大文字と小文字が異なるだけの値もすべて個別値としてカウントするには、COUNT(DISTINCT(%EXACT(expression))) を使用します。NULL 値は COUNT DISTINCT によるカウントの対象になりません。
この文は、Sample.Person にある固有な年齢の個数を返します。
SELECT COUNT(DISTINCT Age) FROM Sample.Person
例 : 個別の列値のカウント
-
COUNT(DISTINCT BY(column) expression) は、column で指定された列にある重複値の行をフィルタで除外し、expression 列にある値の個数を返します。column 列にある NULL 値は個別値としてカウントされます。
以下の文は、個別 (固有) な人名を収めた FavoriteColors 列にある値の個数を返します。
SELECT COUNT(DISTINCT BY(Name) FavoriteColors) FROM Sample.Person
例 : 個別の列値のカウント
-
COUNT(ALL expression) は、expression にあるすべての値の個数を返します。ALL キーワードは、すべての重複値を含む、すべての非 NULL 値をカウントします。キーワードが指定されていない場合は、ALL が既定の動作になります。
-
COUNT( ... expression %FOREACH(column)) は、expression 列の値を、column リストの個別値別にグループ化し、各グループにある値の個数を返します。%FOREACH と GROUP BY は似ています。GROUP BY がクエリ全体に対して機能することに対し、%FOREACH では、クエリ全体の母集団を制限することなく、母集団の一部に対する集約を選択できます。
以下のクエリは、Sample.Person で指定された各人物が記述された行を返します。各行には、その人物の名前と出身州、その州に住んでいる人物の名前の総数が記述されています。
SELECT Name, Home_State, COUNT(Name %FOREACH(Home_State)) AS PersonCountInState FROM Sample.Person
例 : グループ化された値のカウント
-
COUNT( ... expression ... %AFTERHAVING) は、HAVING 節で指定された条件を適用した後でのみ、expression にある行をカウントします。%AFTERHAVING を省略すると、HAVING の条件がカウントで考慮されません。
以下のクエリは、州別にグループ化した名前の個数、および州別にグループ化した名前のうち、"M" で始まる名前の個数を返します。
SELECT Home_State, COUNT(Name) AS NameCount, COUNT(Name %AFTERHAVING) AS MNameCount FROM Sample.Person GROUP BY Home_State HAVING Name LIKE 'M%'
例 : グループ化された値のカウント
引数
expression
カウント対象のデータ値を含む有効な式です。expression には、列の名前、または結果がデータの列となる式を指定できます。expression をサブクエリとして指定することはできません。
column
1 つの列名、またはコンマで区切った複数の列名のリストです。
-
COUNT(expression %FOREACH(column)) 構文では、データのグループ化に使用する列を column で指定し、COUNT で expression 列の値をカウントします。column にストリーム列を指定することはできません。
-
COUNT(DISTINCT BY(column) expression) 構文では、重複行をフィルタで除外するために使用する個別値を収めた列を column で指定し、COUNT で expression 列の値をカウントします。
例
テーブルにある行と列の値のカウント
以下のクエリは、Sample.Person テーブルにある行の合計数を返します。この数には、1 つ以上の列に NULL 値がある行の数も算入されます。
SELECT COUNT(*) AS TotalPersons
FROM Sample.Person
以下のクエリは、Sample.Person にある名前、配偶者名、お気に入りの色の個数を返します。COUNT は、NULL 値を列カウントから除外します。したがって、列ごとの戻り値の個数は、COUNT(*) で返される行の総数と異なるか、その数を下回ることがあります。
SELECT
COUNT(Name) AS People,
COUNT(Spouse) AS PeopleWithSpouses,
COUNT(FavoriteColors) AS PeopleWithColorPref
FROM Sample.Person
個別の列値のカウント
以下のクエリは COUNT DISTINCT を使用して、Sample.Person にある個別の FavoriteColors 値の個数を返しますFavoriteColors 列には、いくつかのデータ値と NULL が記述されています。また、SELECT DISTINCT 節を使用して、個別の FavoriteColors 値ごとに 1 行が返されます。この行数は、COUNT(DISTINCT FavoriteColors) によるカウントよりも 1 大きくなります。DISTINCT は、単一の NULL を個別値としてその行を返しますが、COUNT DISTINCT は NULL をカウントしません。COUNT(DISTINCT BY(FavoriteColors) %ID) では、BY 節があることで NULL が個別値としてカウントされないので、返される値は行数と同じになります。
SELECT
DISTINCT FavoriteColors,
COUNT(DISTINCT FavoriteColors) AS DistColors,
COUNT(DISTINCT BY(FavoriteColors) %ID) AS DistColorPeople
FROM Sample.Person
グループ化された値のカウント
この例でのクエリは、GROUP BY を使用して、列の中で繰り返される値をグループ化し、その固有値 1 つごとに 1 行を返します。このクエリでは、続いて COUNT を使用して、別の列にある値のグループ別カウントを返します。
このクエリは、個別の FavoriteColors 値ごとに 1 行を返します。FavoriteColors が不要であるとすると、このクエリは、NULL 値の行があればそれを返します。各行には、以下の 2 つのカウントが関連付けられています。
-
FavoriteColors オプションの値がある行の数。NULL 値の行はカウントされません。
-
各 FavoriteColors オプションに関連付けられた名前の数。Name に NULL 値がないとすると、このカウントには FavoriteColors が NULL 値であるカウントが算入されます。
SELECT
FavoriteColors,
COUNT(FavoriteColors) AS ColorPreference,
COUNT(Name) AS People
FROM Sample.Person
GROUP BY FavoriteColors
以下のクエリは、Sample.Person にある Home_State 値ごとに該当する人物の行数を返します。
SELECT
Home_State,
COUNT(*) AS AllPersons
FROM Sample.Person
GROUP BY Home_State
以下のクエリは、%AFTERHAVING を使用して、66 歳以上の人が 1 人以上いる各州の個人の行数と 66 歳以上の人数を返します。
SELECT
Home_State,
COUNT(Name) AS AllPersons,
COUNT(Name %AFTERHAVING) AS Seniors
FROM Sample.Person
GROUP BY Home_State
HAVING Age > 65
ORDER BY Home_State
このクエリは %FOREACH キーワードと %AFTERHAVING キーワードの両方を使用します。州ごとに 1 行を返すために GROUP BY を使用し、"A"、"M"、"W" のいずれかで始まる名前の人物のみを抽出するために HAVING を使用します。
SELECT
Home_State,
COUNT(Name) AS NameCount,
COUNT(Name %FOREACH(Home_State)) AS StateNameCount,
COUNT(Name %AFTERHAVING) AS NameCountHaving,
COUNT(Name %FOREACH(Home_State) %AFTERHAVING) AS StateNameCountHaving
FROM Sample.Person
GROUP BY Home_State
HAVING Name LIKE 'A%' OR Name LIKE 'M%' OR Name LIKE 'W%'
ORDER BY Home_State
各州の行には以下のカウント値があります。
-
COUNT(Name) — データベースに記録されているすべての人物。Name が必須であるとすると、このカウントは行の総数と同じです。
-
COUNT(Name %FOREACH(Home_State)) — 州のすべての人物。
-
COUNT(Name %AFTERHAVING) — データベースの中で HAVING の条件を満たすすべての人物。Name が必須であるとすると、この数は行の総数と同じです。
-
COUNT(Name %FOREACH(Home_State) %AFTERHAVING) — 州の中で HAVING の条件を満たすすべての人物。
列の組み合わせにある NULL でない値のカウント
このクエリは、連結演算子 (||) と共に COUNT を使用して、FavoriteColors 列と Home_State 列のどちらにも NULL 値がない行をカウントします。
SELECT COUNT(FavoriteColors||Home_State) AS ColorState
FROM Sample.Person
ストリームにある列の値のカウント
COUNT(expression) を ストリーム列の値のカウントに使用できますが、多少の制約があります。
-
列のカウントには、重複値も含めて、NULL ではない値の総数が必ず算入されます。
-
COUNT DISTINCT expression 節でストリーム・フィールドを指定することはできません。これを実行しようとすると、SQLCODE -37 エラーが返されます。
-
%FOREACH column 節でストリーム・フィールドを指定することはできません。これを実行しようとすると、SQLCODE -37 エラーが返されます。
以下のクエリは、COUNT 関数の有効な使用法を示しています。Title は文字列フィールド、Notes と Picture はストリーム・フィールドです。
SELECT DISTINCT Title,COUNT(Notes),COUNT(Picture %FOREACH(Title))
FROM Sample.Employee
ストリーム・フィールドを指定したこれらのクエリは有効ではありません。
-- Invalid: DISTINCT keyword with stream field
SELECT Title,COUNT(DISTINCT Notes) FROM Sample.Employee
-- Invalid: %FOREACH col-list contains stream field
SELECT Title,COUNT(Notes %FOREACH(Picture))
FROM Sample.Employee
カウントで行が返されない
以下の各例では、COUNT でカウントする行が SELECT クエリで選択されない場合に COUNT が何を返すのかを示しています。クエリに応じて、COUNT は 0 または NULL を返します。
集約関数に対して指定する列を除き、FROM 節のテーブルにある列への参照が SELECT selectItem にない場合、COUNT は 0 を返します。
COUNT は 0 を返す唯一の集約関数です。他のすべての集約関数は NULL を返します。クエリは %ROWCOUNT 1 を返します。クエリのサンプルを以下に示します。
SELECT
COUNT(*) AS Recs, COUNT(Name) AS People,
AVG(Age) AS AvgAge, MAX(Age) AS MaxAge,
CURRENT_TIMESTAMP AS Now
FROM Sample.Employee
WHERE Name %STARTSWITH 'ZZZ'
SELECT selectItem に FROM 節のテーブルにある列への直接参照が記述されている場合、または TOP 0 が指定されている場合、COUNT は NULL を返します。クエリは %ROWCOUNT 0 を返します。クエリのサンプルを以下に示します。
SELECT
COUNT(*) AS Recs,
COUNT(Name) AS People,
$LENGTH(Name) AS NameLen
FROM Sample.Employee WHERE Name %STARTSWITH 'ZZZ'
テーブルを指定しない場合、COUNT(*) は 1 を返します。クエリは %ROWCOUNT 1 を返します。クエリのサンプルを以下に示します。
SELECT COUNT(*) AS Recs
セキュリティおよび特権
COUNT(*) 構文を使用するには、指定したテーブルに対するテーブルレベルの SELECT 特権が必要です。
COUNT(expression) 構文を使用するには、expression で指定した列に対する列レベルの SELECT 特権、または指定したテーブルに対するテーブルレベルの SELECT 特権が必要です。
-
SELECT 特権があるかどうかを確認するには %CHECKPRIV を使用します。
-
テーブルレベルの SELECT 特権があるかどうかを確認するには $SYSTEM.SQL.Security.CheckPrivilege()Opens in a new tab を使用します。
-
特権を割り当てるには GRANT を使用します。
パフォーマンス
COUNT で高いパフォーマンスを得るには、以下のインデックスを定義することを検討します。
-
テーブルを作成したときにビットマップ・エクステント・インデックスが自動的に定義されていない場合は、COUNT(*) 構文でビットマップ・エクステント・インデックスを定義します。
-
COUNT(expression) 構文では、expression.で指定した列にビットスライス・インデックスを定義します。COUNT(expression) のクエリ・プラン最適化によって、カウント対象とする列に既定の照合が自動的に適用されます。
トランザクションの考慮事項
すべての集約関数と同様に、COUNT からは、トランザクションの現在の分離レベルに関係なく、コミットされていない変更も含め、データの現在の状態が返されます。COUNT は以下の動作に従います。
-
挿入されたレコードや更新されたレコードをカウントします。そのレコードの変更がコミットされていなくて、ロールバックされる可能性がある場合でもカウントします。
-
削除されたレコードはカウントしません。その削除がコミットされていなくて、ロールバックされる可能性がある場合でもカウントしません。
詳細は、"SET TRANSACTION" および "START TRANSACTION" を参照してください。