集約(GROUP BY)関数
このドキュメントでは、TiDBでサポートされている集計関数について詳しく説明します。
サポートされている集計関数
このセクションでは、TiDBでサポートされているGROUP BY
集計関数について説明します。
名前 | 説明 |
---|---|
COUNT() | 返された行数のカウントを返します |
COUNT(DISTINCT) | いくつかの異なる値のカウントを返します |
SUM() | 合計を返す |
AVG() | 引数の平均値を返します |
MAX() | 最大値を返す |
MIN() | 最小値を返す |
GROUP_CONCAT() | 連結された文字列を返します |
VARIANCE() 、 VAR_POP() | 母分散を返します |
STD() 、 STDDEV() 、 STDDEV_POP | 母標準偏差を返します |
VAR_SAMP() | 標本分散を返す |
STDDEV_SAMP() | サンプルの標準偏差を返します |
JSON_OBJECTAGG(key, value) | キーと値のペアを含む単一のJSONオブジェクトとして結果セットを返します |
- 特に明記されていない限り、グループ関数は
NULL
の値を無視します。 GROUP BY
句を含まないステートメントでグループ関数を使用する場合、それはすべての行でグループ化することと同じです。
さらに、TiDBは次の集約関数も提供します。
APPROX_PERCENTILE(expr, constant_integer_expr)
この関数は、
expr
のパーセンタイルを返します。constant_integer_expr
引数は、[1,100]
の範囲の定数整数であるパーセンテージ値を示します。パーセンタイルPk (k
はパーセンテージを表す)は、データセットにPk以下の値が少なくともk%
あることを示します。この関数は、返される
expr
の型として数値型と日付と時刻のタイプのみをサポートします。他の返されるタイプの場合、APPROX_PERCENTILE
はNULL
のみを返します。次の例は、
INT
列の50パーセンタイルを計算する方法を示しています。drop table if exists t; create table t(a int); insert into t values(1), (2), (3);select approx_percentile(a, 50) from t;+--------------------------+ | approx_percentile(a, 50) | +--------------------------+ | 2 | +--------------------------+ 1 row in set (0.00 sec)
GROUP_CONCAT()
とAPPROX_PERCENTILE()
の関数を除いて、前述のすべての関数はウィンドウ関数として機能できます。
GROUPBY修飾子
TiDBは現在、 WITH ROLLUP
などのGROUP BY
の修飾子をサポートしていません。今後、サポートを追加する予定です。 TiDB#4250を参照してください。
SQLモードのサポート
TiDBはSQLモードONLY_FULL_GROUP_BY
をサポートしており、有効にすると、TiDBはあいまいな非集計列を含むクエリを拒否します。たとえば、 SELECT
リストの非集計列「b」がGROUP BY
ステートメントに表示されないため、 ONLY_FULL_GROUP_BY
が有効になっている場合、このクエリは無効です。
drop table if exists t;
create table t(a bigint, b bigint, c bigint);
insert into t values(1, 2, 3), (2, 2, 3), (3, 2, 3);
mysql> select a, b, sum(c) from t group by a;
+------+------+--------+
| a | b | sum(c) |
+------+------+--------+
| 1 | 2 | 3 |
| 2 | 2 | 3 |
| 3 | 2 | 3 |
+------+------+--------+
3 rows in set (0.01 sec)
mysql> set sql_mode = 'ONLY_FULL_GROUP_BY';
Query OK, 0 rows affected (0.00 sec)
mysql> select a, b, sum(c) from t group by a;
ERROR 1055 (42000): Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'b' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
TiDBは現在、デフォルトでONLY_FULL_GROUP_BY
モードを有効にしています。
MySQLとの違い
ONLY_FULL_GROUP_BY
の現在の実装は、MySQL5.7の実装よりも厳密ではありません。たとえば、結果が「c」で並べ替えられることを期待して、次のクエリを実行するとします。
drop table if exists t;
create table t(a bigint, b bigint, c bigint);
insert into t values(1, 2, 1), (1, 2, 2), (1, 3, 1), (1, 3, 2);
select distinct a, b from t order by c;
結果を注文するには、最初に重複を排除する必要があります。しかし、そうするために、どの行を保持する必要がありますか?この選択は、「c」の保持値に影響を与えます。これにより、順序が影響を受け、任意になります。
MySQLでは、 ORDER BY
の式のいずれかが次の条件の少なくとも1つを満たさない場合、 DISTINCT
とORDER BY
を持つクエリは無効として拒否されます。
- 式は1つのリストの
SELECT
つに等しい - 式によって参照され、クエリで選択されたテーブルに属するすべての列は、
SELECT
リストの要素です。
ただし、TiDBでは、上記のクエリは有効です。詳細については、 #4254を参照してください。
標準SQLに対する別のTiDB拡張では、 HAVING
句でSELECT
リストのエイリアス式を参照できます。たとえば、次のクエリは、テーブル「orders」で1回だけ発生する「name」値を返します。
select name, count(name) from orders
group by name
having count(name) = 1;
TiDB拡張機能では、集約列のHAVING
句でエイリアスを使用できます。
select name, count(name) as c from orders
group by name
having c = 1;
標準SQLではGROUP BY
句の列式のみが許可されているため、「FLOOR(value / 100)」は非列式であるため、このようなステートメントは無効です。
select id, floor(value/100)
from tbl_name
group by id, floor(value/100);
TiDBは、標準SQLを拡張して、 GROUP BY
節で非列式を許可し、前のステートメントを有効と見なします。
標準SQLでは、 GROUP BY
句のエイリアスも許可されていません。 TiDBは標準SQLを拡張してエイリアスを許可するため、クエリを作成する別の方法は次のとおりです。
select id, floor(value/100) as val
from tbl_name
group by id, val;
サポートされていない集計関数
次の集計関数は、現在TiDBではサポートされていません。あなたはTiDB#7623で私たちの進歩を追跡することができます:
JSON_ARRAYAGG
関連するシステム変数
group_concat_max_len
変数は、 GROUP_CONCAT()
関数のアイテムの最大数を設定します。