重要
このページは英語版のページを機械翻訳しています。原文はこちらからご覧ください。

集約(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]の範囲の定数整数であるパーセンテージ値を示します。パーセンタイルPkkはパーセンテージを表す)は、データセットにPk以下の値が少なくともk%あることを示します。

    この関数は、返されるexprの型として数値タイプ日付と時刻のタイプのみをサポートします。他の返されるタイプの場合、 APPROX_PERCENTILENULLのみを返します。

    次の例は、 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の現在の実装は、 MySQL 5.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つを満たさない場合、 DISTINCTORDER 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()関数のアイテムの最大数を設定します。