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

MaxCompute:SELECT 文における句の実行順序

最終更新日:Mar 26, 2026

MaxCompute では、SELECT 文の句は、記述された順序とは異なる順序で実行されます。この論理的な処理順序を理解することは、正しいクエリを記述し、定義される前に列エイリアスを参照するなどのエラーを回避するのに役立ちます。

仕組み

MaxCompute の SELECT 文は、SELECTFROMWHEREGROUP BYHAVINGORDER BYDISTRIBUTE BYSORT BYLIMIT の 9 つの句をサポートしています。

これらの句は、どの句が存在するかに応じて、2 つのシーケンスのいずれかで処理されます。

シーケンス 1GROUP BYHAVING、または ORDER BY が存在する場合に使用されます:

ステップ処理内容
1FROMソーステーブルを識別します
2WHERE集約前に行をフィルターします
3GROUP BYフィルターされた行をグループ化します
4HAVING集約条件に基づいてグループをフィルターします
5SELECT列を射影し、式を計算します
6ORDER BY結果セットをソートします
7LIMIT出力行数を制限します

シーケンス 2DISTRIBUTE BY または SORT BY が存在する場合に使用されます:

ステップ処理内容
1FROMソーステーブルを識別します
2WHERE行をフィルターします
3SELECT列を射影します
4DISTRIBUTE BYハッシュパーティショニングを使用して、Reducer 間で行を分散させます
5SORT BY各パーティション内で行をソートします
ORDER BYGROUP BY は、同じクエリ内で DISTRIBUTE BY または SORT BY と一緒に使用することはできません。

実行順序での SELECT 文の記述

MaxCompute では、FROMSELECT の前に配置することで、実行順序で句を指定して SELECT 文を記述できます。これにより、論理的なフローが明確になり、読みやすくなります。

標準構文 (記述順):

SELECT [ALL | DISTINCT] <select_expr>, <select_expr>, ...
FROM <table_reference>
[WHERE <where_condition>]
[GROUP BY <col_list>]
[HAVING <having_condition>]
[ORDER BY <order_condition>]
[DISTRIBUTE BY <distribute_condition> [SORT BY <sort_condition>]]
[LIMIT <number>]

実行順序構文 (FROM-first):

FROM <table_reference>
[WHERE <where_condition>]
[GROUP BY <col_list>]
[HAVING <having_condition>]
SELECT [ALL | DISTINCT] <select_expr>, <select_expr>, ...
[ORDER BY <order_condition>]
[DISTRIBUTE BY <distribute_condition> [SORT BY <sort_condition>]]
[LIMIT <number>]

どちらの形式でも、生成される結果は同じです。コード内で実行シーケンスを可視化したい場合は、FROM-first 形式を推奨します。

サンプルデータ

このトピックの例では、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');

-- 2013/china パーティションへのデータ挿入
INSERT INTO sale_detail PARTITION (sale_date='2013', region='china')
VALUES ('s1','c1',100.1),('s2','c2',100.2),('s3','c3',100.3);

-- 2014/shanghai パーティションへのデータ挿入
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   |
+------------+-------------+-------------+------------+------------+
パーティションを指定せずにパーティションテーブルをクエリするには、ステートメントの前に SET odps.sql.allow.fullscan=true; が必要です。本番環境では、全表スキャンを避けるためにパーティションを直接指定してください。

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

次の 2 つのクエリは同等です。1 つ目は標準の記述順を使用し、2 つ目は実行順を使用します。

-- 標準の記述順
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;

-- 実行順 (FROM-first) — 上記のクエリと同等
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      |
+------------+------------+

クエリがステップバイステップでどのように処理されるか:

ステップ中間結果
1FROM sale_detailテーブルからの全 6 行
2WHERE total_price > 100total_price が 100 を超える 5 行 (NULL 行は除外)
3GROUP BY region2 つのグループ:china (3 行) と shanghai (2 行)
4HAVING SUM(total_price) > 300.51 つのグループ:china (合計 = 300.6)
5SELECT region, MAX(total_price)1 行:(china, 100.3)
6ORDER BY regionリージョンで昇順に並べ替えられています。リージョン
7LIMIT 5最大 5 行が返されます

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

次の 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;

-- 実行順 (FROM-first) — 上記のクエリと同等
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   |
+------------+-------------+------------+

クエリがステップバイステップでどのように処理されるか:

ステップ中間結果
1FROM sale_detailテーブルからの全 6 行
2WHERE total_price > 100.23 行:s3 (100.3)、s6 (100.4)、s7 (100.5)
3SELECT shop_name, total_price, region3 つの列が射影されます
4DISTRIBUTE BY regionハッシュパーティショニングを使用して、region によって Reducer 間で行が分散されます
5SORT BY total_price各パーティション内で total_price の昇順で行がソートされます