1. 程式人生 > >阿里雲大資料ACP認證知識點梳理5——基礎SQL語句(DML部分)

阿里雲大資料ACP認證知識點梳理5——基礎SQL語句(DML部分)

insert overwrite table sale_detail_insert partition (sale_date='2013', region='china')
insert into table sale_detail_insert partition (sale_date='2013', region='china')
注:Insert into與Insert overwrite的區別是:Insert into會向表或表的分割槽中追加資料,而Insert overwrite會在向表或分割槽中插入資料前清空表中的原有資料。在insert overwrite|into後需要加入table關鍵字,不是直接使用tablename。當Insert的目標表是分割槽表時,指定分割槽值,語法中不允許使用函式等表示式。目前INSERT OVERWRITE還不支援指定插入列的功能,暫時只能用INSERT INTO。不支援insert into到hash clustering表。

insert overwrite table sale_detail_insert partition (sale_date='2013', region='china')
select shop_name, customer_id, total_price, sale_date, region from sale_detail;
-- 報錯返回,sale_date,region為分割槽列,不允許出現在靜態分割槽的insert語句中。
注:向某個分割槽插入資料時,分割槽列不允許出現在select列表中。

create table sale_detail_multi like sale_detail;
from

sale_detail
insert overwrite table sale_detail_multi partition (sale_date='2010', region='china' )
select shop_name, customer_id, total_price where .....
insert overwrite table sale_detail_multi partition (sale_date='2011', region='china' )
select shop_name, customer_id, total_price where .....;
注:MaxCompute SQL支援在一個語句中插入不同的結果表或者分割槽實現多路輸出。一般情況下,單個SQL中最多可以寫256路輸出,超過256路,則報語法錯誤。對於分割槽表,同一個目標分割槽不允許出現多次。對於未分割槽表,該表不能出現多次。對於同一張分割槽表的不同分割槽,不能同時有Insert overwrite和Insert into操作,否則報錯返回。

insert overwrite table sale_detail_dypart partition (sale_date, region)
select shop_name,customer_id,total_price,sale_date,region from sale_detail;

注:可以在分割槽中指定一個分割槽列名,但不給出值。相應地,在select子句中的對應列來提供分割槽的值。此時sale_detail表中,sale_date的值決定目標表的sale_date分割槽值,region的值決定目標表的region分割槽值。動態分割槽中,select_statement欄位和目標表動態分割槽的對應是按欄位順序決定的。如該示例中,select語句若寫成select shop_name,customer_id,total_price,region,sale_date from sale_detail;,則sale_detail表中,region值決定決定目標表的 sale_date分割槽值,sale_date的值決定目標表的region分割槽值。動態分割槽列必須在select列表中(如sale_date和region).

insert overwrite table sales partition (region='china', sale_date)
select shop_name,customer_id,total_price,region from sale_detail;

注:失敗返回,不能僅指定低階子分割槽,而動態插入高階分割槽。

select 語句

select * from sale_detail;

select shop_name from sale_detail;

select * from sale_detail where shop_name like 'hang%';

注:當使用Select語句屏顯時,目前最多隻能顯示10000行結果。當Select作為子句時,無此限制,Select子句會將全部結果返回給上層查詢。select分割槽表時禁止全表掃描。

select * from (select region from sale_detail) t where region = 'shanghai';
注:巢狀子查詢中,select region from sale_detail的結果暫時存放在t中作為一箇中轉,查詢結果反饋到上層就是,select * from t where region='shanghai';

screenshot

注:where子句支援的過濾條件,不等於為<>不是=!

select sale_detail.* from sale_detail where sale_detail.sale_date >= '2008' and sale_detail.sale_date <= '2014';

注:用and語句設定查詢的分割槽範圍。

select sale_detail.* from sale_detail where sale_detail.sale_date between '2008' and  '2014';

注:用between、and語句設定查詢的分割槽範圍。

group by語句:

select region from sale_detail group by region;
-- 直接使用輸入表列名作為group by的列,可以執行
select sum(total_price) from sale_detail group by region;
-- 以region值分組,返回每一組的銷售額總量,可以執行
select region, sum(total_price) from sale_detail group by region;
-- 以region值分組,返回每一組的region值(組內唯一)及銷售額總量,可以執行
select region as r from sale_detail group by r;
-- 使用select列的別名執行,報錯返回
select 2 + total_price as r from sale_detail group by 2 + total_price;
-- 必須使用列的完整表示式
select region, total_price from sale_detail group by region;
-- 報錯返回,select的所有列中,沒有使用聚合函式的列,必須出現在group by中
select region, total_price from sale_detail group by region, total_price;
-- 可以執行

注:分組查詢,一般group by和聚合函式配合使用。在Select中包含聚合函式時有以下規則:用group by的key可以是輸入表的列名也可以是由輸入表的列構成的表示式,不允許是Select語句的輸出列的別名。group by操作通常是先於Select操作的,因此group by只能接受輸入表的列或表示式為key。

ORDER BY語句:

注:對所有資料按照某幾列進行全域性排序。如果您希望按照降序對記錄進行排序,可以使用DESC關鍵字。由於是全域性排序,order by必須與limit共同使用。在使用order by排序時,Null會被認為比任何值都小,這個行為與MySQL一致,但是與Oracle不一致。與group by不同,order by後面必須加Select列的別名,當Select某列時,如果沒有指定列的別名,將列名作為列的別名。

select * from sale_detail order by region;
-- 報錯返回,order by沒有與limit共同使用
select * from sale_detail order by region limit 100;
select region as r from sale_detail order by region limit 100;
-- 報錯返回,order by後面必須加列的別名。
select region as r from sale_detail order by r limit 100;

distribute by語句

select region from sale_detail distribute by region;
-- 列名即是別名,可以執行
select region as r from sale_detail distribute by region;
-- 報錯返回,後面必須加列的別名。
select region as r from sale_detail distribute by r;

sort by語句:

注:區域性排序,語句前必須加distribute by。實際上sort by是對distribute by的結果進行區域性排序。必須使用Select的輸出列別名。

select region from sale_detail distribute by region sort by region;
select region as r from sale_detail sort by region;
-- 沒有distribute by,報錯退出

select * from (select shop_name from sale_detail) a;

注:子查詢必須要有別名。

select * from sale_detail where region = 'hangzhou'
        union all
select * from sale_detail where region = 'shanghai';

注:UNION ALL將兩個或多個Select操作返回的資料集聯合成一個數據集,如果結果有重複行時,會返回所有符合條件的行,不進行重複行的去重處理。union all/union操作對應的各個查詢的列個數和型別必須一致(如果型別不一致,需保證經過隱式轉換後型別是一致的)。一般情況下,MaxCompute最多允許256個表的union all/union,超過此限制報語法錯誤。

JOIN語句

左連線:
select a.shop_name as ashop, b.shop_name as bshop from shop a

    **left outer join** sale_detail b **on** a.shop_name=b.shop_name;
-- 由於表shop及sale_detail中都有shop_name列,因此需要在select子句中使用別名進行區分。

右連線:
select a.shop_name as ashop, b.shop_name as bshop from shop a

    **right outer join** sale_detail b **on** a.shop_name=b.shop_name;

全連線:
select a.shop_name as ashop, b.shop_name as bshop from shop a

   ** full outer join** sale_detail b **on** a.shop_name=b.shop_name;

注:連線條件,只允許and連線的等值條件。只有在MAPJOIN中,可以使用不等值連線或者使用or連線多個條件。

MAPJOIN語句:

select /* + mapjoin(a) */
        a.shop_name,
        b.customer_id,
        b.total_price
    from shop a join sale_detail b
    on a.shop_name = b.shop_name;

注:left outer join的左表必須是大表。right outer join的右表必須是大表。inner join左表或右表均可以作為大表。full outer join不能使用MapJoin。MapJoin支援小表為子查詢。使用MapJoin時,需要引用小表或是子查詢時,需要引用別名。在MapJoin中,可以使用不等值連線或者使用or連線多個條件。目前,MaxCompute在MapJoin中最多支援指定8張小表,否則報語法錯誤。如果使用MapJoin,則所有小表佔用的記憶體總和不得超過512MB。多個表Join時,最左邊的兩個表不能同時是MapJoin的表。