MaxCompute, tabloları birleştirmek ve birleştirme ile sorgu koşullarını karşılayan verileri döndürmek için JOIN işlemlerini kullanmanıza olanak tanır. Bu konuda aşağıdaki JOIN işlemleri açıklanmaktadır: LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN, INNER JOIN, NATURAL JOIN, örtük JOIN ve çoklu JOIN işlemleri.
Genel Bakış
MaxCompute aşağıdaki türlerdeki JOIN işlemlerini destekler:
-
LEFT OUTER JOINBu işlem
LEFT JOINolarak da adlandırılır. LEFT OUTER JOIN, sağ tablodaki herhangi bir satırla eşleşmeyenler dahil olmak üzere sol tablodaki tüm satırları döndürür.NotBir
JOINişleminde sol tablo genellikle büyük, sağ tablo ise küçük bir tablodur. Sağ tablodaki bazı satırların değerleri tekrarlıyorsa art arda birden fazlaLEFT JOINişlemi uygulamanız önerilmez. Art arda birden fazlaLEFT JOINişlemi uygulanırsa veri şişmesi meydana gelebilir ve işleriniz kesintiye uğrayabilir. -
RIGHT OUTER JOINBu işlem
RIGHT JOINolarak da adlandırılır. RIGHT OUTER JOIN, sol tablodaki herhangi bir satırla eşleşmeyenler dahil olmak üzere sağ tablodaki tüm satırları döndürür. -
FULL OUTER JOINBu işlem
FULL JOINolarak da adlandırılır. FULL OUTER JOIN, hem sol hem de sağ tablodaki tüm satırları döndürür. -
INNER JOININNERanahtar sözcüğü ihmal edilebilir.INNER JOINsol ve sağ tablolar arasında bir eşleşme varsa veri satırlarını döndürür. -
NATURAL JOINBir
NATURAL JOINişleminde iki tabloyu birleştirmek için kullanılan alanlar, iki tablonun ortak alanlarına göre belirlenir. MaxComputeOUTER NATURAL JOINişlemini destekler.USINGyan tümcesini kullanırsanızNATURAL JOINişlemi ortak alanları yalnızca bir kez döndürür. -
Örtük JOIN işlemi
JOIN anahtar sözcüğünü belirtmenize gerek kalmadan örtük bir
JOINişlemi uygulayabilirsiniz. -
Çoklu JOIN işlemleri
MaxCompute birden fazla
JOINişlemini destekler.JOINişlemlerinin önceliklerini belirtmek için parantez () kullanabilirsiniz. Parantez () içine alınan birJOINişleminin önceliği daha yüksektir.
Bir SQL deyimi
WHEREyan tümcesi içeriyorsa veWHEREyan tümcesinden önceJOINyan tümcesini kullanıyorsanız önceJOINişlemi uygulanır. ArdındanJOINişleminden elde edilen sonuçlarWHEREyan tümcesinde belirtilen koşullara göre filtrelenir. Nihai sonuç bir tablodaki tüm satırlar değil iki tablonun kesişimidir.-
OUTER JOIN ONyan tümcesindeki JOIN dışı bir koşulunJOINişleminin giriş verisi olarak kullanılıp kullanılmayacağını kontrol etmek için odps.task.sql.outerjoin.ppd parametresini kullanabilirsiniz. Bu parametreyi proje veya oturum düzeyinde yapılandırabilirsiniz.Bu parametreyi
falseolarak ayarlarsanızONyan tümcesindeki JOIN dışı koşul, JOIN işleminin alt sorgusu içinWHEREyan tümcesindeki koşul olarak değerlendirilir. Bu standart dışı bir davranıştır. JOIN dışı koşuluWHEREyan tümcesinde belirtmeniz önerilir.Bu parametreyi
falseolarak ayarlarsanız aşağıdaki SQL deyimleri eşdeğerdir. Parametreyitrueolarak ayarlarsanız iki SQL deyimi eşdeğer değildir.
SELECT A.*, B.* FROM A LEFT JOIN B ON A.c1 = B.c1 and A.c2='xxx'; SELECT A.*, B.* FROM (SELECT * FROM A WHERE c2='xxx') A LEFT JOIN B ON A.c1 = B.c1;
Kullanım notları
Bir JOIN işleminde hesaplama için JOIN işleminin key is not null filtre koşulu otomatik olarak eklenir. Birleştirme anahtarının değeri null olan satır JOIN işleminden sonra filtrelenir.
Sınırlamalar
Bir JOIN işlemi uygularken aşağıdaki sınırlamalara dikkat edin:
MaxCompute
CROSS JOINişlemini desteklemez. CROSS JOIN işlemi,ONyan tümcesinde koşul belirtmenize gerek kalmadan iki tabloyu birleştirir.Eşitlik birleştirmeleri kullanmalı ve koşulları
ANDile birleştirmelisiniz. Eşitsizlik birleştirmelerini kullanabilir veya birMAPJOINişleminde birden fazla koşuluORkullanarak birleştirebilirsiniz. Daha fazla bilgi için bkz. MAPJOIN.
Söz dizimi
<table_reference> JOIN <table_factor> [<join_condition>]
| <table_reference> {LEFT OUTER|RIGHT OUTER|FULL OUTER|INNER|NATURAL} JOIN <table_reference> <join_condition>
table_reference: gereklidir.
JOINişleminin uygulandığı sol tablo için sorgu deyimidir. Bu parametrenin değeritable_name [alias] | table_query [alias] |...biçimindedir.table_factor: gereklidir. Sağ tablo veya
JOINişleminin uygulandığı bir tablo için sorgu deyimidir. Bu parametrenin değeritable_name [alias] | table_subquery [alias] |...biçimindedir.join_condition: isteğe bağlıdır. Bir
JOINkoşulu, bir veya daha fazla eşitlik ifadesinin birleşimidir. Bu parametrenin değerion equality_expression [and equality_expression]...biçimindedir.equality_expressionbir eşitlik ifadesidir.
WHERE yan tümcesinde bölüm budama koşulları belirtilirse bölüm budama hem üst hem de alt tablolarda etkili olur. ON yan tümcesinde bölüm budama koşulları belirtilirse bölüm budama yalnızca alt tabloda etkili olur. Sonuç olarak üst tablo için tam tablo taraması çalıştırılır. Daha fazla bilgi için bkz. Bölüm budamanın etkinliğini değerlendirme.
Örnek veriler
Bu konudaki örnekleri daha iyi anlamanız için örnek kaynak veriler sağlanmıştır. Aşağıdaki deyimler sale_detail ve sale_detail_jt tablolarının nasıl oluşturulacağını ve bu tablolara nasıl veri ekleneceğini göstermektedir.
-- Create two partitioned tables named sale_detail and sale_detail_jt.
CREATE TABLE if NOT EXISTS sale_detail
(
shop_name STRING,
customer_id STRING,
total_price DOUBLE
)
PARTITIONED BY (sale_date STRING, region STRING);
CREATE TABLE if NOT EXISTS sale_detail_jt
(
shop_name STRING,
customer_id STRING,
total_price DOUBLE
)
PARTITIONED BY (sale_date STRING, region STRING);
-- Add partitions to the two tables.
ALTER TABLE sale_detail ADD PARTITION (sale_date='2013', region='china') PARTITION (sale_date='2014', region='shanghai');
ALTER TABLE sale_detail_jt ADD PARTITION (sale_date='2013', region='china');
-- Insert data into the tables.
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);
INSERT INTO sale_detail_jt PARTITION (sale_date='2013', region='china') VALUES ('s1','c1',100.1),('s2','c2',100.2),('s5','c2',100.2);
-- Query data from the sale_detail and sale_detail_jt tables. Sample statements:
SET odps.sql.allow.fullscan=true;
SELECT * FROM sale_detail;
-- The following result is returned:
+------------+-------------+-------------+------------+------------+
| 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;
SELECT * FROM sale_detail_jt;
-- The following result is returned:
+------------+-------------+-------------+------------+------------+
| shop_name | customer_id | total_price | sale_date | region |
+------------+-------------+-------------+------------+------------+
| s1 | c1 | 100.1 | 2013 | china |
| s2 | c2 | 100.2 | 2013 | china |
| s5 | c2 | 100.2 | 2013 | china |
+------------+-------------+-------------+------------+------------+
-- Create a table for the JOIN operation.
SET odps.sql.allow.fullscan=true;
CREATE TABLE shop AS SELECT shop_name, customer_id, total_price FROM sale_detail;
Örnekler
Aşağıdaki örnekler Örnek veriler temel alınarak JOIN kullanımını göstermektedir.
-
Örnek 1: LEFT OUTER JOIN. Örnek deyimler:
-- The full table scan feature must be enabled for partitioned tables. Otherwise, the JOIN operation fails. SET odps.sql.allow.fullscan=true; -- Both the sale_detail_jt and sale_detail tables have the shop_name column. You must use aliases to distinguish between the columns in the SELECT statement. SELECT a.shop_name AS ashop, b.shop_name AS bshop FROM sale_detail_jt a LEFT OUTER JOIN sale_detail b ON a.shop_name=b.shop_name;Aşağıdaki sonuç döndürülür:
+------------+------------+ | ashop | bshop | +------------+------------+ | s2 | s2 | | s1 | s1 | | s5 | NULL | +------------+------------+ -
Örnek 2: RIGHT OUTER JOIN. Örnek deyimler:
-- The full table scan feature must be enabled for partitioned tables. Otherwise, the JOIN operation fails. SET odps.sql.allow.fullscan=true; -- Both the sale_detail_jt and sale_detail tables have the shop_name column. You must use aliases to distinguish between the columns in the SELECT statement. SELECT a.shop_name AS ashop, b.shop_name AS bshop FROM sale_detail_jt a RIGHT OUTER JOIN sale_detail b ON a.shop_name=b.shop_name;Aşağıdaki sonuç döndürülür:
+------------+------------+ | ashop | bshop | +------------+------------+ | s1 | s1 | | s2 | s2 | | NULL | s3 | | NULL | null | | NULL | s6 | | NULL | s7 | +------------+------------+ -
Örnek 3: FULL OUTER JOIN. Örnek deyimler:
-- The full table scan feature must be enabled for partitioned tables. Otherwise, the JOIN operation fails. SET odps.sql.allow.fullscan=true; -- Both the sale_detail_jt and sale_detail tables have the shop_name column. You must use aliases to distinguish between the columns in the SELECT statement. SELECT a.shop_name AS ashop, b.shop_name AS bshop FROM sale_detail_jt a FULL OUTER JOIN sale_detail b ON a.shop_name=b.shop_name;Aşağıdaki sonuç döndürülür:
+------------+------------+ | ashop | bshop | +------------+------------+ | NULL | s3 | | NULL | s6 | | s2 | s2 | | NULL | null | | NULL | s7 | | s1 | s1 | | s5 | NULL | +------------+------------+ -
Örnek 4: INNER JOIN. Örnek deyimler:
-- The full table scan feature must be enabled for partitioned tables. Otherwise, the JOIN operation fails. SET odps.sql.allow.fullscan=true; -- Both the sale_detail_jt and sale_detail tables have the shop_name column. You must use aliases to distinguish between the columns in the SELECT statement. SELECT a.shop_name AS ashop, b.shop_name AS bshop FROM sale_detail_jt a INNER JOIN sale_detail b ON a.shop_name=b.shop_name;Aşağıdaki sonuç döndürülür:
+------------+------------+ | ashop | bshop | +------------+------------+ | s2 | s2 | | s1 | s1 | +------------+------------+ -
Örnek 5: NATURAL JOIN. Örnek deyimler:
-- The full table scan feature must be enabled for partitioned tables. Otherwise, the JOIN operation fails. SET odps.sql.allow.fullscan=true; -- Perform a NATURAL JOIN operation. SELECT * FROM sale_detail_jt NATURAL JOIN sale_detail; -- The preceding statement is equivalent to the following statement: SELECT sale_detail_jt.shop_name AS shop_name, sale_detail_jt.customer_id AS customer_id, sale_detail_jt.total_price AS total_price, sale_detail_jt.sale_date as sale_date, sale_detail_jt.region as region from sale_detail_jt INNER JOIN sale_detail ON sale_detail_jt.shop_name=sale_detail.shop_name AND sale_detail_jt.customer_id=sale_detail.customer_id and sale_detail_jt.total_price=sale_detail.total_price AND sale_detail_jt.sale_date=sale_detail.sale_date AND sale_detail_jt.region=sale_detail.region;Aşağıdaki sonuç döndürülür:
+------------+-------------+-------------+------------+------------+ | shop_name | customer_id | total_price | sale_date | region | +------------+-------------+-------------+------------+------------+ | s1 | c1 | 100.1 | 2013 | china | | s2 | c2 | 100.2 | 2013 | china | +------------+-------------+-------------+------------+------------+ -
Örnek 6: Örtük JOIN. Örnek deyimler:
-- The full table scan feature must be enabled for partitioned tables. Otherwise, the JOIN operation fails. SET odps.sql.allow.fullscan=true; -- Perform an implicit JOIN operation. SELECT * FROM sale_detail_jt, sale_detail WHERE sale_detail_jt.shop_name = sale_detail.shop_name; -- The preceding statement is equivalent to the following statement: SELECT * FROM sale_detail_jt JOIN sale_detail ON sale_detail_jt.shop_name = sale_detail.shop_name;Aşağıdaki sonuç döndürülür:
+------------+-------------+-------------+------------+------------+------------+--------------+--------------+------------+------------+ | shop_name | customer_id | total_price | sale_date | region | shop_name2 | customer_id2 | total_price2 | sale_date2 | region2 | +------------+-------------+-------------+------------+------------+------------+--------------+--------------+------------+------------+ | s2 | c2 | 100.2 | 2013 | china | s2 | c2 | 100.2 | 2013 | china | | s1 | c1 | 100.1 | 2013 | china | s1 | c1 | 100.1 | 2013 | china | +------------+-------------+-------------+------------+------------+------------+--------------+--------------+------------+------------+ -
Örnek 7: Çoklu JOIN işlemleri. Öncelik belirtilmemiştir. Örnek deyimler:
-- The full table scan feature must be enabled for partitioned tables. Otherwise, the JOIN operation fails. SET odps.sql.allow.fullscan=true; -- Both the sale_detail_jt and sale_detail tables have the shop_name column. You must use aliases to distinguish between the columns in the SELECT statement. SELECT a.* FROM sale_detail_jt a FULL OUTER JOIN sale_detail b ON a.shop_name=b.shop_name FULL OUTER JOIN sale_detail c ON a.shop_name=c.shop_name;Aşağıdaki sonuç döndürülür:
+------------+-------------+-------------+------------+------------+ | shop_name | customer_id | total_price | sale_date | region | +------------+-------------+-------------+------------+------------+ | s5 | c2 | 100.2 | 2013 | china | | NULL | NULL | NULL | NULL | NULL | | NULL | NULL | NULL | NULL | NULL | | NULL | NULL | NULL | NULL | NULL | | NULL | NULL | NULL | NULL | NULL | | NULL | NULL | NULL | NULL | NULL | | NULL | NULL | NULL | NULL | NULL | | s1 | c1 | 100.1 | 2013 | china | | NULL | NULL | NULL | NULL | NULL | | s2 | c2 | 100.2 | 2013 | china | | NULL | NULL | NULL | NULL | NULL | +------------+-------------+-------------+------------+------------+ -
Örnek 8: Çoklu JOIN işlemleri. JOIN işlemlerinin önceliklerini belirtmek için parantez () kullanın. Örnek deyimler:
-- The full table scan feature must be enabled for partitioned tables. Otherwise, the JOIN operation fails. SET odps.sql.allow.fullscan=true; -- Perform multiple JOIN operations. Use parentheses () to specify the priority. SELECT * FROM shop JOIN (sale_detail_jt JOIN sale_detail ON sale_detail_jt.shop_name = sale_detail.shop_name) ON shop.shop_name=sale_detail_jt.shop_name;Aşağıdaki sonuç döndürülür:
+------------+-------------+-------------+------------+------------+------------+--------------+--------------+------------+------------+------------+--------------+--------------+------------+------------+ | shop_name | customer_id | total_price | sale_date | region | shop_name2 | customer_id2 | total_price2 | sale_date2 | region2 | shop_name3 | customer_id3 | total_price3 | sale_date3 | region3 | +------------+-------------+-------------+------------+------------+------------+--------------+--------------+------------+------------+------------+--------------+--------------+------------+------------+ | s2 | c2 | 100.2 | 2013 | china | s2 | c2 | 100.2 | 2013 | china | s2 | c2 | 100.2 | 2013 | china | | s1 | c1 | 100.1 | 2013 | china | s1 | c1 | 100.1 | 2013 | china | s1 | c1 | 100.1 | 2013 | china | +------------+-------------+-------------+------------+------------+------------+--------------+--------------+------------+------------+------------+--------------+--------------+------------+------------+ -
Örnek 9: Bölgesi china olan ve iki tabloda shop_name alanı aynı değere sahip kayıtların sayısını sorgulamak için
JOINveWHEREkullanın. sale_detail tablosundaki tüm kayıtlar korunur. Örnek deyimler:-- The full table scan feature must be enabled for partitioned tables. Otherwise, the JOIN operation fails. SET odps.sql.allow.fullscan=true; -- Execute the following SQL statement: SELECT a.shop_name ,a.customer_id ,a.total_price ,b.total_price FROM (SELECT * FROM sale_detail WHERE region = "china") a LEFT JOIN (SELECT * FROM sale_detail_jt WHERE region = "china") b ON a.shop_name = b.shop_name;Aşağıdaki sonuç döndürülür:
+------------+-------------+-------------+--------------+ | shop_name | customer_id | total_price | total_price2 | +------------+-------------+-------------+--------------+ | s1 | c1 | 100.1 | 100.1 | | s2 | c2 | 100.2 | 100.2 | | s3 | c3 | 100.3 | NULL | +------------+-------------+-------------+--------------+Yanlış kullanım için örnek deyim:
SELECT a.shop_name ,a.customer_id ,a.total_price ,b.total_price FROM sale_detail a LEFT JOIN sale_detail_jt b ON a.shop_name = b.shop_name WHERE a.region = "china" AND b.region = "china";Aşağıdaki sonuç döndürülür:
+------------+-------------+-------------+--------------+ | shop_name | customer_id | total_price | total_price2 | +------------+-------------+-------------+--------------+ | s1 | c1 | 100.1 | 100.1 | | s2 | c2 | 100.2 | 100.2 | +------------+-------------+-------------+--------------+Döndürülen sonuç sale_detail tablosundaki tüm satırlar değil iki tablonun kesişimidir.