すべてのプロダクト
Search
ドキュメントセンター

MaxCompute:SELECT ステートメントの順序

最終更新日:Aug 25, 2026

MaxCompute は、SELECT ステートメントの句を、構文に記述された順序とは異なる順序で実行します。 この実行順序を理解することは、特に GROUP BYHAVING、および MaxCompute 固有の句である DISTRIBUTE BYSORT BY を使用する際に、正しいクエリロジックを記述する上で役立ちます。

実行順序

SELECT 構文 では、SELECTFROMWHEREGROUP BYHAVINGWINDOWQUALIFYORDER BYDISTRIBUTE BYSORT BY、および LIMIT の句を使用できます。

MaxCompute は、使用する句に応じて、これらを 2 つのシーケンスのいずれかで実行します。

ORDER BY および GROUP BY は、DISTRIBUTE BY または SORT BY と一緒に使用することはできません。

シーケンス 1 :クエリに GROUP BYORDER BY、または LIMIT が含まれる場合に使用します。

  1. FROM

  2. WHERE

  3. GROUP BY

  4. HAVING

  5. SELECT

  6. ORDER BY

  7. LIMIT

シーケンス 2 :クエリに DISTRIBUTE BY または SORT BY が含まれる場合に使用します。

  1. FROM

  2. WHERE

  3. SELECT

  4. DISTRIBUTE BY

  5. SORT BY

SELECT は構文上は最初に記述されますが、FROMWHEREGROUP BY、および HAVING が処理された後にのみ実行されます。

実行順序に沿ったステートメントの記述

クエリロジックを読みやすくするために、MaxCompute では SELECT ステートメントを SELECT からではなく FROM から始める実行順序に沿って記述できます。 2 つの形式は同等です:

-- 標準形式 (SELECT が先)
SELECT region, max(total_price)
FROM sale_detail
WHERE total_price > 100
GROUP BY region
HAVING sum(total_price) > 300.5
ORDER BY region
LIMIT 5;

-- 実行順序形式 (FROM が先) - 上記のステートメントと同等
FROM sale_detail
WHERE total_price > 100
GROUP BY region
HAVING sum(total_price) > 300.5
SELECT region, max(total_price)
ORDER BY region
LIMIT 5;

実行順序に沿って記述する場合の構文は次のとおりです:

FROM <table_reference>
[WHERE <where_condition>]
[GROUP BY <col_list>]
[HAVING <having_condition>]
[WINDOW <window_name> AS (<window_definition>)]
[QUALIFY <expression>]
SELECT [ALL | DISTINCT] <select_expr>, <select_expr>, ...
[ORDER BY <order_condition>]
[DISTRIBUTE BY <distribute_condition> [SORT BY <sort_condition>]]
[LIMIT <number>]

サンプルデータ

このトピックの例では、パーティションテーブル sale_detail を使用します。 次のステートメントを実行して、テーブルを作成し、データを挿入します:

-- パーティションテーブル sale_detail を作成
CREATE TABLE IF NOT EXISTS sale_detail
(
  shop_name     string,
  customer_id   string,
  total_price   double
)
PARTITIONED BY (sale_date string, region string);

-- パーティションの追加
ALTER TABLE sale_detail ADD
  PARTITION (sale_date='2013', region='china')
  PARTITION (sale_date='2014', region='shanghai');

-- データの挿入
INSERT INTO sale_detail PARTITION (sale_date='2013', region='china')
  VALUES ('s1','c1',100.1),('s2','c2',100.2),('s3','c3',100.3);

INSERT INTO sale_detail PARTITION (sale_date='2014', region='shanghai')
  VALUES ('null','c5',null),('s6','c6',100.4),('s7','c7',100.5);

テーブル全体を表示するには:

SET odps.sql.allow.fullscan=true;
SELECT * FROM sale_detail;
+------------+-------------+-------------+------------+------------+
| shop_name  | customer_id | total_price | sale_date  | region     |
+------------+-------------+-------------+------------+------------+
| s1         | c1          | 100.1       | 2013       | china      |
| s2         | c2          | 100.2       | 2013       | china      |
| s3         | c3          | 100.3       | 2013       | china      |
| null       | c5          | NULL        | 2014       | shanghai   |
| s6         | c6          | 100.4       | 2014       | shanghai   |
| s7         | c7          | 100.5       | 2014       | shanghai   |
+------------+-------------+-------------+------------+------------+

例 1:シーケンス 1 (GROUP BY と ORDER BY)

パーティションを指定せずにパーティションテーブルをクエリするには、フルテーブルスキャンが必要です。 ステートメントの前に SET odps.sql.allow.fullscan=true; を追加して有効にしてください。

次の 2 つのステートメントは同等です。 どちらもシーケンス 1 を使用します。

-- 標準形式
SET odps.sql.allow.fullscan=true;
SELECT region, max(total_price)
FROM sale_detail
WHERE total_price > 100
GROUP BY region
HAVING sum(total_price) > 300.5
ORDER BY region
LIMIT 5;

-- 実行順序形式
SET odps.sql.allow.fullscan=true;
FROM sale_detail
WHERE total_price > 100
GROUP BY region
HAVING sum(total_price) > 300.5
SELECT region, max(total_price)
ORDER BY region
LIMIT 5;

結果:

+------------+------------+
| region     | _c1        |
+------------+------------+
| china      | 100.3      |
+------------+------------+

句の実行プロセス:

  1. FROM sale_detail :テーブルから行を読み取ります。

  2. WHERE total_price > 100total_price が 100 を超える行のみを保持します。

  3. GROUP BY region :残りの行を region ごとにグループ化します。

  4. HAVING sum(total_price) > 300.5 :合計価格が 300.5 を超えるグループのみを保持します。

  5. SELECT region, max(total_price) :各グループから region と最大価格を射影します。

  6. ORDER BY region :結果を region でソートします。

  7. LIMIT 5 :最初の 5 行を返します。

例 2:シーケンス 2 (DISTRIBUTE BY と SORT BY)

次の 2 つのステートメントは同等です。 どちらもシーケンス 2 を使用します。

-- 標準形式
SET odps.sql.allow.fullscan=true;
SELECT shop_name,
       total_price,
       region
FROM   sale_detail
WHERE  total_price > 100.2
DISTRIBUTE BY region
SORT BY total_price;

-- 実行順序形式
SET odps.sql.allow.fullscan=true;
FROM   sale_detail
WHERE  total_price > 100.2
SELECT shop_name,
       total_price,
       region
DISTRIBUTE BY region
SORT BY total_price;

結果:

+------------+-------------+------------+
| shop_name  | total_price | region     |
+------------+-------------+------------+
| s3         | 100.3       | china      |
| s6         | 100.4       | shanghai   |
| s7         | 100.5       | shanghai   |
+------------+-------------+------------+

句の実行プロセス:

  1. FROM sale_detail :テーブルから行を読み取ります。

  2. WHERE total_price > 100.2total_price が 100.2 を超える行のみを保持します。

  3. SELECT shop_name, total_price, region :3 つの列を射影します。

  4. DISTRIBUTE BY regionregion 列のハッシュパーティショニングを使用して、レデューサーに行を分散させます。

  5. SORT BY total_price :各レデューサー内で、行を total_price の昇順でソートします。