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

MaxCompute:SELECT 文の実行順序

最終更新日:Mar 27, 2026

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

実行シーケンス

SELECT 構文は、SELECTFROMWHEREGROUP BYHAVINGWINDOWQUALIFYORDER BYDISTRIBUTE BYSORT BYLIMIT の句をサポートしています。

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

ORDER BYGROUP 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 BYHAVING が処理された後にのみ実行されます。

実行順序での文の記述

クエリロジックを読みやすくするために、MaxCompute では SELECT を先頭にするのではなく、FROM を先頭にして実行順序で SELECT 文を記述できます。この 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 — 残りの行をリージョンでグループ化します。

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

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

  6. ORDER BY 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 region — region 列のハッシュパーティショニングを使用して、リデューサー間で行を分散させます。

  5. SORT BY total_price — 各リデューサー内で total_price によって行を昇順にソートします。