Alt sorgu, başka bir sorgunun içinde yer alan bir SELECT ifadesidir ve diğer sorguların sonuç kümelerini sorgulamanıza olanak tanır. Toplam değerlerin hesaplanması, satır varlığının kontrol edilmesi, başka bir sorgunun sonucuna göre verilerin filtrelenmesi, ilişkili güncelleme veya silme işlemlerinin yapılması, tek bir değer döndürmek için JOIN işleminin basitleştirilmesi, sonucun dış sorgu için türetilmiş tablo olarak kullanılması, sıralama veya gruplama temeli sağlanması ve satır bazlı karşılaştırmaların yapılması yaygın kullanım durumlarıdır. Bu konu, MaxCompute'in desteklediği alt sorgu türlerini ve bunların nasıl kullanılacağını açıklar.
Özellikler
MaxCompute aşağıdaki alt sorgu türlerini destekler:
-
Temel alt sorgu, bir sorgunun
FROMyan tümcesinde kullanılır ve türetilmiş tablo olarak işlev görür. Sorgu içindeki karmaşık hesaplamalar veya veri dönüşümleri için bu türü kullanabilirsiniz. -
Dış sorgudan, alt sorgu tarafından döndürülen değer kümesiyle eşleşen satırları seçmek için
WHEREyan tümcesinde IN alt sorgusu kullanın. -
NOT IN alt sorgusu, dış sorgudan alt sorgunun sonuç kümesiyle eşleşen satırları kaldırmak için
WHEREyan tümcesinde kullanılır. -
EXISTS alt sorgusu, alt sorgunun herhangi bir satır döndürüp döndürmediğini test eder. İçerdikleri gerçek verilere ihtiyaç duymadan ilişkili satırların varlığını kontrol etmek için bu tür uygundur.
-
NOT EXISTS alt sorgusu, dış sorgudan alt sorguda eşleşmesi olmayan satırları seçer.
-
Skaler alt sorgu tek bir değer (tek satır ve tek sütun) döndürür. Genellikle SELECT listesinde veya
WHEREya daHAVINGyan tümcesinde koşul değeri olarak kullanılır.
Çalıştırma sırasında, sorgu optimize edicisi genellikle skaler, IN, NOT IN, EXISTS veya NOT EXISTS gibi bazı alt sorguları JOIN işlemlerine dönüştürür. MAPJOIN, verimli bir broadcast join algoritmasıdır. Bir alt sorgunun sonucunun küçük bir tablo olduğunu belirlerseniz, MAPJOIN algoritmasını açıkça kullanmak için alt sorguya bir ipucu ekleyebilirsiniz. Daha fazla bilgi için bkz. SUBQUERY_MAPJOIN İPUCU.
Örnek veriler
Bu konudaki örnekler, sale_detail adlı bölümlenmiş bir tablo kullanır. Tabloyu oluşturup doldurmak için aşağıdaki ifadeleri ç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 |
+------------+-------------+-------------+------------+------------+
Temel alt sorgu
Standart bir sorgu ana bir tablo üzerinde çalışır. Ancak, bir sorgu başka bir select ifadesi üzerinde de çalışabilir. Bu tür sorguya alt sorgu denir. from yan tümcesinde, alt sorgu bir tablo olarak ele alınabilir ve bir join işlemi kullanılarak diğer tablolarla veya alt sorgularla birleştirilebilir. join işlemleri hakkında daha fazla bilgi için bkz. JOIN.
-
Sözdizimi
select <select_expr> from (<select_statement>) [<sq_alias_name>]; -
Parametreler
select_expr: Gereklidir. Format
col1_name, col2_name, regular expression,...şeklindedir; sorgulanacak normal sütunları, bölüm anahtar sütunlarını veya düzenli ifadeleri belirtir.select_statement: Gereklidir. Alt sorgu ifadesi. Format hakkında daha fazla bilgi için bkz. SELECT sözdizimi.
sq_alias_name: İsteğe bağlıdır. Alt sorgunun takma adı.
table_name: Gereklidir. Ana tablonun adı.
-
Örnekler
-
Örnek 1: Aşağıdaki komut temel alt sorgu sözdizimine bir örnek sunar.
set odps.sql.allow.fullscan=true; select * from (select shop_name from sale_detail) a;Sonuç:
+------------+ | shop_name | +------------+ | s1 | | s2 | | s3 | | null | | s6 | | s7 | +------------+
-
Örnek 2:
fromyan tümcesinde, alt sorgu bir tablo olarak ele alınabilir ve diğer tablolarla veya alt sorgularla birjoinişleminde kullanılabilir. Örnek bir komut aşağıdaki gibidir.-- Create a table and then perform a join operation. create table shop as select shop_name,customer_id,total_price from sale_detail; select a.shop_name, a.customer_id, a.total_price from (select * from shop) a join sale_detail on a.shop_name = sale_detail.shop_name;Sonuç:
+------------+-----------------+-----------------+ | _c0 | scalarsubquery1 | scalarsubquery2 | +------------+-----------------+-----------------+ | null | c5 | NULL | | s6 | c6 | 100.4 | | s7 | c7 | 100.5 | | s1 | c1 | 100.1 | | s2 | c2 | 100.2 | | s3 | c3 | 100.3 | +------------+-----------------+-----------------+
-
IN alt sorgusu
in subquery left semi join ile benzer şekilde kullanılır.
-
Sözdizimi
-
Format 1
select <select_expr1> from <table_name1> where <select_expr2> in (select <select_expr3> from <table_name2>); -- This statement is equivalent to the following LEFT SEMI JOIN statement. select <select_expr1> from <table_name1> <alias_name1> left semi join <table_name2> <alias_name2> on <alias_name1>.<select_expr2> = <alias_name2>.<select_expr3>;NotEğer
select_expr2bir bölüm anahtar sütunu ise, alt sorguselect <select_expr2> from <table_name2>ayrı bir işte çalıştırılır ve birsemi joinişlemine dönüştürülmez. Çalıştırma sonuçları daha sonraselect_expr2ile karşılaştırılır.table_name1içindeki bölümlerinselect_expr2değerleri döndürülen sonuçlarda yoksa okunmaz. Bu sayede bölüm budama etkili kalır. -
Format 2
MaxCompute yalnızca
in subquerydeğil, aynı zamanda ilişkili koşulları da destekler. Alt sorgudakiwhere <table_name2_colname> = <table_name1>.<colname>yan tümcesi ilişkili bir koşuldur. MaxCompute 1.0, hem alt sorgudaki kaynak tabloya hem de dış sorgudaki kaynak tabloya başvuran ifadeleri desteklemiyordu. MaxCompute 2.0 bu kullanımı destekler; burada bu filtre koşulu, birsemi joiniçindekionkoşulunun bir parçasını oluşturur.select <select_expr1> from <table_name1> where <select_expr2> in (select <select_expr3> from <table_name2> where <table_name1>.<col_name> = <table_name2>.<col_name>);NotMaxCompute, bir
joinkoşulu olarak kullanılmayan birin subqueryöğesini destekler; örneğin, birwhereyan tümcesinin dışında yer alıyorsa veya birwhereyan tümcesinde yer alıp birjoinkoşuluna dönüştürülemiyorsa. Bu durumda, alt sorgu birsemi joinişlemine dönüştürülemez, alt sorguyu çalıştırmak için ayrı bir iş başlatılmalıdır ve ilişkili koşullar desteklenmez. -
Format 3
Yukarıdaki yeteneklere dayanarak, MaxCompute PostgreSQL'in çoklu sütun desteğiyle uyumludur. Uygulamayı birden fazla alt sorguya ayırmaya kıyasla, bu yaklaşım bir JOIN sürecini azaltır ve hesaplama kaynaklarından tasarruf sağlar. Desteklenen çoklu sütun kullanımları aşağıdaki gibidir:
inifadesinden sonra gelen ifade, basit bir çoklu sütunlu SELECT ifadesi olabilir.inifadesinden sonra gelen ifadeye toplama işlevleri ekleyebilirsiniz. Daha fazla bilgi için bkz. Toplama işlevleri.inifadesinden sonraki ifade bir sabit olabilir.
-
-
Parametreler
select_expr1: Gereklidir. Format
col1_name, col2_name, regular expression,...şeklindedir. Bu parametre, sorgulanacak normal sütunları, bölüm anahtar sütunlarını veya düzenli ifadeleri belirtir.table_name1, table_name2: Gereklidir. Tabloların adları.
select_expr2, select_expr3: Gereklidir. table_name1 ve table_name2 tablolarının eşleştirilmiş sütun adları.
col_name: Gereklidir. Bir sütunun adı.
-
Kullanım notları
INiçeren bir alt sorgu kullanırken, NULL değerlere sahip satırlar otomatik olarak alt sorgunun sonuç kümesinden kaldırılır. -
Örnekler
-
Örnek 1: Format 1'in alt sorgu sözdizimini kullanın.
set odps.sql.allow.fullscan=true; select * from sale_detail where total_price in (select total_price from shop);Sonuç:
+-----------+-------------+-------------+-----------+--------+ | 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 | | s6 | c6 | 100.4 | 2014 | shanghai | | s7 | c7 | 100.5 | 2014 | shanghai | +-----------+-------------+-------------+-----------+--------+ -
Örnek 2: Format 2'nin alt sorgu sözdizimini kullanın.
set odps.sql.allow.fullscan=true; select * from sale_detail where total_price in (select total_price from shop where customer_id = shop.customer_id);Sonuç:
+-----------+-------------+-------------+-----------+--------+ | 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 | | s6 | c6 | 100.4 | 2014 | shanghai | | s7 | c7 | 100.5 | 2014 | shanghai | +-----------+-------------+-------------+-----------+--------+ -
Örnek 3: Çoklu sütunlu SELECT ifadesi kullanma.
-- For easier understanding, sample data is reconstructed here. create table if not exists t1(a bigint,b bigint,c bigint,d bigint,e bigint); create table if not exists t2(a bigint,b bigint,c bigint,d bigint,e bigint); insert into table t1 values (1,3,2,1,1),(2,2,1,3,1),(3,1,1,1,1),(2,1,1,0,1),(1,1,1,0,1); insert into table t2 values (1,3,5,0,1),(2,2,3,1,1),(3,1,1,0,1),(2,1,1,0,1),(1,1,1,0,1); -- Scenario 1: The expression after `in` is a simple multi-column SELECT statement. select a, b from t1 where (c, d) in (select a, b from t2 where e = t1.e); -- The following result is returned. +------------+------------+ | a | b | +------------+------------+ | 1 | 3 | | 2 | 2 | | 3 | 1 | +------------+------------+ -- Scenario 2: Use an aggregate function in the expression after `in`. select a, b from t1 where (c, d) in (select max(a), b from t2 where e = t1.e group by b having max(a) > 0); -- The following result is returned. +------------+------------+ | a | b | +------------+------------+ | 2 | 2 | +------------+------------+ -- Scenario 3: The expression after `in` is a constant. select a, b from t1 where (c, d) in ((1, 3), (1, 1)); -- The following result is returned. +------------+------------+ | a | b | +------------+------------+ | 2 | 2 | | 3 | 1 | +------------+------------+
-
NOT IN alt sorgusu
not in subquery left anti join ile benzerdir, ancak özdeş değildir. Alt sorgu tarafından döndürülen belirtilen sütun herhangi bir NULL değer içeriyorsa, not in ifadesi NULL olarak değerlendirilir. Bu durum where koşulunun başarısız olmasına ve hiçbir veri döndürülmemesine neden olur. Bu durum left anti join işleminden farklıdır.
-
Sözdizimi
-
Format 1
select <select_expr1> from <table_name1> where <select_expr2> not in (select <select_expr2> from <table_name2>); -- This statement is equivalent to the following LEFT ANTI JOIN statement. select <select_expr1> from <table_name1> <alias_name1> left anti join <table_name2> <alias_name2> on <alias_name1>.<select_expr1> = <alias_name2>.<select_expr2>;NotEğer
select_expr2bir bölüm anahtar sütunu ise,select <select_expr2> from <table_name2>alt sorgusu ayrı bir işte çalıştırılır ve biranti joinişlemine dönüştürülmez. Çalıştırma sonucu,select_expr2değerleriyle karşılaştırılır. Döndürülen sonuç kümesindeselect_expr2değerleri bulunmayantable_name1içindeki bölümler okunmaz; bu sayede bölüm budama etkili kalır. -
Format 2
MaxCompute yalnızca
NOT INalt sorgularını değil, aynı zamanda ilişkili koşulları da destekler. Alt sorgudakiwhere <table_name2_colname> = <table_name1>.<colname>yan tümcesi ilişkili bir koşuldur. MaxCompute 1.0, hem alt sorgudaki kaynak tabloya hem de dış sorgunun kaynak tablosuna başvuran ifadeleri desteklemiyordu. MaxCompute 2.0 bu kullanımı destekler. Bu filtre koşulu, birANTI JOINiçindekiONkoşulunun bir parçasını oluşturur.select <select_expr1> from <table_name1> where <select_expr2> not in (select <select_expr2> from <table_name2> where <table_name2_colname> = <table_name1>.<colname>);NotMaxCompute, bir
joinkoşulu olarak kullanılmadığındanot in subqueryöğesini destekler; örneğin, birwhereyan tümcesinin dışında yer alıyorsa veya birwhereyan tümcesinde yer alıp birjoinkoşuluna dönüştürülemiyorsa. Bu durumda, biranti joinişlemine dönüştürülemez. Alt sorguyu çalıştırmak için ayrı bir iş başlatılmalıdır ve ilişkili koşullar desteklenmez. -
Format 3
Yukarıdaki yeteneklere dayanarak, MaxCompute PostgreSQL'in çoklu sütun desteğiyle uyumludur. Uygulamayı birden fazla alt sorguya ayırmaya kıyasla, bu yaklaşım bir JOIN sürecini azaltır ve hesaplama kaynaklarından tasarruf sağlar. Desteklenen çoklu sütun kullanımları aşağıdaki gibidir:
not inifadesinden sonraki ifade, birden fazla sütun döndüren basit bir SELECT ifadesi olabilir.not inifadesini takip eden bir ifadeye toplama işlevleri ekleyebilirsiniz. Daha fazla bilgi için bkz. Toplama işlevleri.not inifadesini takip eden ifade bir sabit olabilir.
-
-
Parametreler
select_expr1: Gereklidir. Format
col1_name, col2_name, regular expression,...şeklindedir. Bu parametre, sorgulanacak normal sütunları, bölüm anahtar sütunlarını veya düzenli ifadeleri belirtir.table_name1, table_name2: Gereklidir. Tabloların adları.
select_expr2, select_expr3: Gereklidir. table_name1 ve table_name2 tablolarının eşleştirilmiş sütun adları.
col_name: Gereklidir. Bir sütunun adı.
-
Kullanım notları
NOT INiçeren bir alt sorgu kullanırken, NULL değerlere sahip satırlar otomatik olarak alt sorgunun sonuç kümesinden kaldırılır. -
Örnekler
-
Örnek 1: Format 1'in alt sorgu sözdizimini kullanın.
-- Create a new table named shop1 and insert data into it. create table shop1 as select shop_name,customer_id,total_price from sale_detail; insert into shop1 values ('s8','c1',100.1); select * from shop1 where shop_name not in (select shop_name from sale_detail);Sonuç:
+------------+-------------+-------------+ | shop_name | customer_id | total_price | +------------+-------------+-------------+ | s8 | c1 | 100.1 | +------------+-------------+-------------+ -
Örnek 2: Format 2'nin alt sorgu sözdizimini kullanın.
set odps.sql.allow.fullscan=true; select * from shop1 where shop_name not in (select shop_name from sale_detail where customer_id = shop1.customer_id);Sonuç:
+------------+-------------+-------------+ | shop_name | customer_id | total_price | +------------+-------------+-------------+ | s8 | c1 | 100.1 | +------------+-------------+-------------+ -
Örnek 3:
not in subquerybirjoinkoşulu olarak kullanılmaz. Aşağıda bir komut örneği verilmiştir.set odps.sql.allow.fullscan=true; select * from shop1 where shop_name not in (select shop_name from sale_detail) and total_price < 100.3;whereyan tümcesiandiçerdiğinden, sorgu biranti joinişlemine dönüştürülemez ve bunun yerine ayrı bir işte alt sorgu olarak çalıştırılır.Sonuç:
+------------+-------------+-------------+ | shop_name | customer_id | total_price | +------------+-------------+-------------+ | s8 | c1 | 100.1 | +------------+-------------+-------------+ -
Örnek 4: Alt sorgu sonucu bir
NULLdeğer içeriyorsa, hiçbir veri döndürülmez. Aşağıdaki komut buna bir örnek sunar.-- Create a new table named sale and insert data into it. create table if not exists sale ( shop_name string, customer_id string, total_price double ) partitioned by (sale_date string, region string); alter table sale add partition (sale_date='2013', region='china'); insert into sale partition (sale_date='2013', region='china') values ('null','null',null),('s2','c2',100.2),('s3','c3',100.3),('s8','c8',100.8); set odps.sql.allow.fullscan=true; select * from sale where shop_name not in (select shop_name from sale_detail);Sonuç:
+------------+-------------+-------------+------------+------------+ | shop_name | customer_id | total_price | sale_date | region | +------------+-------------+-------------+------------+------------+ +------------+-------------+-------------+------------+------------+ -
Örnek 5: Çoklu sütunlu SELECT ifadesi kullanma.
-- For easier understanding, sample data is reconstructed here. This data is the same as the sample data in the IN subquery section. create table if not exists t1(a bigint,b bigint,c bigint,d bigint,e bigint); create table if not exists t2(a bigint,b bigint,c bigint,d bigint,e bigint); insert into table t1 values (1,3,2,1,1),(2,2,1,3,1),(3,1,1,1,1),(2,1,1,0,1),(1,1,1,0,1); insert into table t2 values (1,3,5,0,1),(2,2,3,1,1),(3,1,1,0,1),(2,1,1,0,1),(1,1,1,0,1); -- Scenario 1: The expression after `not in` is a simple multi-column SELECT statement. select a, b from t1 where (c, d) not in (select a, b from t2 where e = t1.e); -- The following result is returned. +------------+------------+ | a | b | +------------+------------+ | 2 | 1 | | 1 | 1 | +------------+------------+ -- Scenario 2: Use an aggregate function in the expression after `not in`. select a, b from t1 where (c, d) not in (select max(a), b from t2 where e = t1.e group by b having max(a) > 0); -- The following result is returned. +------------+------------+ | a | b | +------------+------------+ | 1 | 3 | | 3 | 1 | | 2 | 1 | | 1 | 1 | +------------+------------+ -- Scenario 3: The expression after `not in` is a constant. select a, b from t1 where (c, d) not in ((1, 3), (1, 1)); -- The following result is returned. +------------+------------+ | a | b | +------------+------------+ | 1 | 3 | | 2 | 1 | | 1 | 1 | +------------+------------+
-
EXISTS alt sorgusu
Bir exists subquery kullandığınızda, alt sorguda en az bir satır veri varsa True, aksi takdirde False döner.
MaxCompute yalnızca ilişkili koşullar içeren where alt sorgularını destekler. Bir exists subquery bir left semi join olarak uygulanır.
-
Sözdizimi
select <select_expr> from <table_name1> where exists (select <select_expr> from <table_name2> where <table_name2_colname> = <table_name1>.<colname>); -
Parametreler
select_expr: Gereklidir. Format
col1_name, col2_name, regular expression,...şeklindedir; sorgulanacak normal sütunları, bölüm anahtar sütunlarını veya düzenli ifadeleri belirtir.table_name1, table_name2: Gereklidir. Tabloların adları.
col_name: Gereklidir. Bir sütunun adı.
-
Örnek
set odps.sql.allow.fullscan=true; select * from sale_detail where exists (select * from shop where customer_id = sale_detail.customer_id); -- This statement is equivalent to the following statement. select * from sale_detail a left semi join shop b on a.customer_id = b.customer_id;Sonuç:
+------------+-------------+-------------+------------+------------+ | shop_name | customer_id | total_price | sale_date | region | +------------+-------------+-------------+------------+------------+ | null | c5 | NULL | 2014 | shanghai | | s6 | c6 | 100.4 | 2014 | shanghai | | s7 | c7 | 100.5 | 2014 | shanghai | | s1 | c1 | 100.1 | 2013 | china | | s2 | c2 | 100.2 | 2013 | china | | s3 | c3 | 100.3 | 2013 | china | +------------+-------------+-------------+------------+------------+
NOT EXISTS alt sorgusu
Bir not exists subquery kullandığınızda, alt sorguda veri yoksa True döner. Aksi takdirde False döner.
MaxCompute yalnızca ilişkili koşul içeren where alt sorgularını destekler. Bir not exists subquery bir left anti join olarak uygulanır.
-
Sözdizimi
select <select_expr> from <table_name1> where not exists (select <select_expr> from <table_name2> where <table_name2_colname> = <table_name1>.<colname>); -
Parametreler
select_expr: Gereklidir. Format
col1_name, col2_name, regular expression,...şeklindedir; sorgulanacak normal sütunları, bölüm anahtar sütunlarını veya düzenli ifadeleri belirtir.table_name1, table_name2: Gereklidir. Tabloların adları.
col_name: Gereklidir. Bir sütunun adı.
-
Örnek
set odps.sql.allow.fullscan=true; select * from sale_detail where not exists (select * from shop where shop_name = sale_detail.shop_name); -- This statement is equivalent to the following statement. select * from sale_detail a left anti join shop b on a.shop_name = b.shop_name;Sonuç:
+------------+-------------+-------------+------------+------------+ | shop_name | customer_id | total_price | sale_date | region | +------------+-------------+-------------+------------+------------+ +------------+-------------+-------------+------------+------------+
Skaler alt sorgu
Bir alt sorgu tek bir satır ve tek bir sütun döndürüyorsa, skaler işlemlerde skaler değer olarak kullanılabilir. Bir sorgu yalnızca bir satır döndürüyorsa, sonucu değiştirmeden sorguyu bir max veya min işlevi içine alabilirsiniz. Skaler alt sorgular ayrıca çoklu sütun kullanımını destekler. Örneğin, bir skaler alt sorgu SELECT listesinde çoklu sütunlu ifade olarak kullanılabilir, ancak yalnızca eşitlik ifadeleri desteklenir. Ayrıca SELECT listesinde bir BOOLEAN ifadesi olarak da kullanılabilir, ancak yalnızca eşitlik karşılaştırmaları için geçerlidir. where yan tümcesinde çoklu sütun karşılaştırmaları desteklenir, ancak yalnızca eşitlik için geçerlidir.
-
Sözdizimi
-
Format 1
select <select_expr> from <table_name1> where (<select count(*) from <table_name2> where <table_name2_colname> = <table_name1>.<colname>) <scalar_operator> <scalar_value>; -- This statement is equivalent to the following statement. select <table_name1>.<select_expr> from <table_name1> left semi join (select <colname>, count(*) from <table_name2> group by <colname> having count(*) <scalar_operator> <scalar_value>) <table_name2> on <table_name1>.<colname> = <table_name2>.<colname>;Notselect count(*) from <table_name2> where <table_name2_colname> = <table_name1>.<colname>çıktısı bir satır kümesidir. Bu ifade yalnızca bir satır ve bir sütun döndürür. Bu nedenle, skaler olarak ele alınabilir. Ancak uygulama sırasında, mümkün olduğunca birjoinişlemine dönüştürülür.-
Derleyici, derleme zamanında tam olarak bir satır ve bir sütun döndürdüğünü teyit edebiliyorsa bir alt sorgu skaler olarak kullanılabilir. Bu durum yalnızca çalışma zamanında belirlenebiliyorsa, derleyici hata döndürür. İfadenin derleyici tarafından kabul edilmesi için iki gereksinimi karşılaması gerekir:
Alt sorgunun
SELECTlistesi, tablo değerli işlevin parametre listesinde olmayan bir toplama işlevi kullanır.Toplama işlevi içeren alt sorguda bir
group byyan tümcesi bulunmaz.
-
Format 2
select (<select_statement>) from <table_name>;
-
-
Parametreler
select_expr: Gereklidir. Format
col1_name, col2_name, regular expression,...şeklindedir; sorgulanacak normal sütunları, bölüm anahtar sütunlarını veya düzenli ifadeleri belirtir.table_name1, table_name2: Gereklidir. Tabloların adları.
col_name: Gereklidir. Bir sütunun adı.
scalar_operator: Gereklidir. Örneğin, büyüktür (
>), küçüktür (<), eşittir (=), büyük eşittir (>=) veya küçük eşittir (<=).scalar_value: Gereklidir. Skaler bir değer.
select_statement: Gereklidir. Alt sorgu ifadesi. Format 2'yi kullanıyorsanız, alt sorgu yalnızca bir satır döndürmelidir. Format hakkında daha fazla bilgi için bkz. SELECT sözdizimi.
-
Sınırlamalar
-
Bir
scalar subquerydış sorgudan sütunlara başvurabilir, ancak birden fazlascalar subqueryifadesi iç içe geçtiğinde, bir alt sorgu yalnızca kendisine en yakın dış sorgudan sütunlara başvurabilir.-- Allowed operation. select * from t1 where (select count(*) from t2 where t1.a = t2.a) = 3; -- Disallowed operation. The nested subquery references `t1.a`, which is two levels out, not from the immediate outer layer. select * from t1 where (select count(*) from t2 where (select count(*) from t3 where t3.a = t1.a) = 2) = 3;
-
-
Örnekler
-
Örnek 1: Aşağıdaki komut yaygın bir kullanım durumuna örnek sunar.
set odps.sql.allow.fullscan=true; select * from shop where (select count(*) from sale_detail where sale_detail.shop_name = shop.shop_name) >= 1;Sonuç:
+------------+-------------+-------------+ | shop_name | customer_id | total_price | +------------+-------------+-------------+ | s1 | c1 | 100.1 | | s2 | c2 | 100.2 | | s3 | c3 | 100.3 | | null | c5 | NULL | | s6 | c6 | 100.4 | | s7 | c7 | 100.5 | +------------+-------------+-------------+ -
Örnek 2: Çoklu sütunlu SELECT ifadesi kullanma.
-- For easier understanding, sample data is reconstructed here. create table if not exists ts(a bigint,b bigint,c double); create table if not exists t(a bigint,b bigint,c double); insert into table ts values (1,3,4.0),(1,3,3.0); insert into table t values (1,3,4.0),(1,3,5.0); -- Scenario 1: A SELECT column is a scalar subquery expression with multiple columns. Only equality expressions are supported. Invalid usage: `select (select a, b from t where c > ts.c) as (a, b), a from ts;` select (select a, b from t where c = ts.c) as (a, b), a from ts; -- The following result is returned. +------------+------------+------------+ | a | b | a2 | +------------+------------+------------+ | 1 | 3 | 1 | | NULL | NULL | 1 | +------------+------------+------------+ -- Scenario 2: The SELECT column is a Boolean expression. Only equality comparisons are supported. Invalid usage: `select (a,b) > (select a,b from ts where c = t.c) from t;` select (a,b) = (select a,b from ts where c = t.c) from t; -- The following result is returned. +------+ | _c0 | +------+ | true | | false | +------+ -- Scenario 3: The `where` clause supports multi-column comparisons. Only equality comparisons are supported. Invalid usage: `select * from t where (a,b) > (select a,b from ts where c = t.c);` select * from t where c > 3.0 and (a,b) = (select a,b from ts where c = t.c); -- The following result is returned. +------------+------------+------------+ | a | b | c | +------------+------------+------------+ | 1 | 3 | 4.0 | +------------+------------+------------+ select * from t where c > 3.0 or (a,b) = (select a,b from ts where c = t.c); -- The following result is returned. +------------+------------+------------+ | a | b | c | +------------+------------+------------+ | 1 | 3 | 4.0 | | 1 | 3 | 5.0 | +------------+------------+------------+ -
Örnek 3: Format 2'nin alt sorgu sözdizimini kullanma.
set odps.sql.allow.fullscan=true; select (select * from sale_detail where shop_name='s1') from sale_detail;Sonuç:
+------------+-----------------+-----------------+-----------------+-----------------+ | _c0 | scalarsubquery1 | scalarsubquery2 | scalarsubquery3 | scalarsubquery4 | +------------+-----------------+-----------------+-----------------+-----------------+ | s1 | c1 | 100.1 | 2013 | china | | s1 | c1 | 100.1 | 2013 | china | | s1 | c1 | 100.1 | 2013 | china | | s1 | c1 | 100.1 | 2013 | china | | s1 | c1 | 100.1 | 2013 | china | | s1 | c1 | 100.1 | 2013 | china | +------------+-----------------+-----------------+-----------------+-----------------+
-
İlgili konular
Alt sorguların aşırı kullanılması veya verimsiz yazılması, özellikle büyük veri ortamlarında sorgu performansını düşürebilir. Sorgu verimliliğini artırmak için geçici tablo, materyalize edilmiş görünüm gibi alternatifleri göz önünde bulundurun veya birden fazla alt sorguyu JOIN işlemlerine yeniden yapılandırın. Daha fazla bilgi için bkz. Materyalize edilmiş görünümler ve JOIN.