MaxCompute, bir SELECT deyiminin yan tümcelerini, yazım sözdiziminde göründükleri sıradan farklı bir sırayla yürütür. Bu yürütme sırasını anlamak; özellikle GROUP BY, HAVING ve DISTRIBUTE BY ile SORT BY gibi MaxCompute'e özel yan tümceleri kullanırken doğru sorgu mantığı oluşturmanıza yardımcı olur.
Yürütme dizileri
SELECT sözdizimi aşağıdaki yan tümceleri destekler: SELECT, FROM, WHERE, GROUP BY, HAVING, WINDOW, QUALIFY, ORDER BY, DISTRIBUTE BY, SORT BY ve LIMIT.
MaxCompute bu yan tümceleri, kullandığınız yan tümcelere bağlı olarak iki diziden biriyle yürütür.
ORDER BYveGROUP BYyan tümceleri,DISTRIBUTE BYveyaSORT BYile birlikte kullanılamaz.
Dizi 1 — Sorgunuz GROUP BY, ORDER BY veya LIMIT içeriyorsa kullanılır:
FROMWHEREGROUP BYHAVINGSELECTORDER BYLIMIT
Dizi 2 — Sorgunuz DISTRIBUTE BY veya SORT BY içeriyorsa kullanılır:
FROMWHERESELECTDISTRIBUTE BYSORT BY
Yazım sözdiziminde SELECT ilk sırada görünse de bu yan tümce, FROM, WHERE, GROUP BY ve HAVING işlendikten sonra yürütülür.
Deyimleri yürütme sırasına göre yazma
Sorgu mantığını daha okunabilir hale getirmek için MaxCompute, SELECT deyimlerini yürütme sırasına göre yazmanıza olanak tanır; yani SELECT yerine önce FROM yazarsınız. İki biçim eşdeğerdir:
-- Standard form (SELECT first)
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;
-- Execution-order form (FROM first) — equivalent to the statement above
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;
Tam yürütme sırası sözdizimi şöyledir:
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>]
Örnek veriler
Bu konudaki örnekler, sale_detail adlı bölümlenmiş bir tablo kullanır. Tabloyu oluşturup doldurmak için aşağıdaki deyimleri çalıştırın:
-- Create a partitioned table named 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);
-- Add partitions
ALTER TABLE sale_detail ADD
PARTITION (sale_date='2013', region='china')
PARTITION (sale_date='2014', region='shanghai');
-- Insert data
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);
Tablonun tamamını görüntülemek için:
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 |
+------------+-------------+-------------+------------+------------+
Örnekler
Örnek 1: Dizi 1 (GROUP BY ve ORDER BY)
Bölümler belirtilmeden bölümlenmiş bir tabloda sorgu yapmak tam tablo taraması gerektirir. Etkinleştirmek için deyimden önce SET odps.sql.allow.fullscan=true; ekleyin.
Aşağıdaki iki deyim eşdeğerdir. Her ikisi de Dizi 1'i kullanır.
-- Standard form
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;
-- Execution-order form
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;
Sonuç:
+------------+------------+
| region | _c1 |
+------------+------------+
| china | 100.3 |
+------------+------------+
Yan tümcelerin yürütülme şekli:
FROM
sale_detail— Tablodan satırları okur.WHERE
total_price > 100— Yalnızcatotal_pricedeğeri 100'den büyük olan satırları tutar.GROUP BY
region— Kalan satırları bölgeye göre gruplandırır.HAVING
sum(total_price) > 300.5— Toplam fiyatı 300,5'ten büyük olan grupları tutar.SELECT
region, max(total_price)— Her gruptaki bölgeyi ve maksimum fiyatı yansıtır.ORDER BY
region— Sonucu bölgeye göre sıralar.LIMIT
5— İlk beş satırı döndürür.
Örnek 2: Dizi 2 (DISTRIBUTE BY ve SORT BY)
Aşağıdaki iki deyim eşdeğerdir. Her ikisi de Dizi 2'yi kullanır.
-- Standard form
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;
-- Execution-order form
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;
Sonuç:
+------------+-------------+------------+
| shop_name | total_price | region |
+------------+-------------+------------+
| s3 | 100.3 | china |
| s6 | 100.4 | shanghai |
| s7 | 100.5 | shanghai |
+------------+-------------+------------+
Yan tümcelerin yürütülme şekli:
FROM
sale_detail— Tablodan satırları okur.WHERE
total_price > 100.2— Yalnızcatotal_pricedeğeri 100,2'den büyük olan satırları tutar.SELECT
shop_name, total_price, region— Üç sütunu yansıtır.DISTRIBUTE BY
region— Satırları, region sütunundaki hash bölümlemesini kullanarak indirgeyicilere dağıtır.SORT BY
total_price— Her indirgeyicideki satırlarıtotal_pricedeğerine göre artan düzende sıralar.