ODPS开发大全:入门篇(2)

本文涉及的产品
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
云原生大数据计算服务MaxCompute,500CU*H 100GB 3个月
简介: ODPS开发大全:入门篇

 DQL


  • SELECT语句


1. SELECT语法


[with <cte>[, ...] ]SELECT [all | distinct] <SELECT_expr>[, <except_expr>][, <replace_expr>] ...       from <table_reference>       [where <where_condition>]       [group by {<col_list>|rollup(<col_list>)}]       [having <having_condition>]       [window <window_clause>]       [order by <order_condition>]       [distribute by <distribute_condition> [sort by <sort_condition>]|[ cluster by <cluster_condition>] ]       [limit <number>]


下面将介绍SELECT命令格式及如何实现嵌套查询、分组查询、排序等操作。


2. SELECT语序


--语法顺序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>]

场景1:from->where->group by->having->select->order by->limit

场景2:from->where->select->distribute by->sort by


3. WITH子句


with A as (SELECT 1 as C),B as (SELECT * from A) SELECT * from B;


在同一WITH子句中的CTE必须具有唯一的名字。

在WITH子句中定义的CTE仅对在同一WITH子句中的其他CTE可以使用。


4. 列表达式


------------------------------------------------------------------------------例子 --读取表xxxx_detail的列shop_nameSELECT xxxx_name from xxxx_detail;--查询表xxxx_detail中region列数据,如果有重复值时仅显示一条。SELECT distinct region from xxxx_detail;--选出xxxx_detail表中列名不为xxxx_name的所有列SELECT `(xxxx_name)?+.+` from xxxx_detail;--去重多列时,distinct的作用域是SELECT的列集合,不是单个列。SELECT distinct region, xxxx_date from xxxx_detail;


用列名指定要读取的列。

用星号(*)代表查询所有的列。

可以使用正则表达式。

在选取的列名前可以使用distinct去掉重复字段,只返回去重后的值。


5. 排除列


--读取xxxx_detail表的数据,并排除region列的数据。------------------------------------------------------------------------------例子SELECT * except(region) from xxxx_detail;


当希望读取表内大多数列的数据,同时要排除表中少数列的数据时。

表示读取表数据时会排除指定列(col1、col2)的数据。


6. WHERE


--配合关系运算符,筛选满足指定条件的数据。关系运算符包含:  >、<、=、>=、<=、<>  like、rlike  in、not in  between…and------------------------------------------------------------------------------例子SELECT * from xxxx_detailwhere xxxx_date >= '2008' and xxxx_date <= '2014';--等价于如下语句。SELECT * from xxxx_detail where xxxx_date between '2008' and '2014';


where子句为过滤条件。如果表是分区表,可以实现列裁剪。


7. GROUP BY


------------------------------------------------------------------------------例子
--直接使用输入表列名region作为group by的列,即以region值分组SELECT region from xxxx_detail group by region;
--以region值分组,返回每一组的销售额总量。SELECT sum(xxxx_price) from xxxx_detail group by region;
--以region值分组,返回每一组的region值(组内唯一)及销售额总量。SELECT region, sum (xxxx_price) from xxxx_detail group by region;


group by操作优先级高于SELECT操作,因此group by的取值是SELECT输入表的列名或由输入表的列构成的表达式。需要注意的是:

group by取值为正则表达式时,必须使用列的完整表达式。

SELECT语句中没有使用聚合函数的列必须出现在GROUP BY中。


8. HAVING


------------------------------------------------------------------------------例子--为直观展示数据呈现效果,向sale_detail表中追加数据。insert into sale_detail partition (sale_date='2014', region='shanghai')   values ('null','c5',null),('s6','c6',100.4),('s7','c7',100.5);--使用having子句配合聚合函数实现过滤。SELECT region,sum(total_price) from sale_detail group by region having sum(total_price)<305;


通常HAVING子句与聚合函数一起使用,实现过滤。


9. ORDER BY



------------------------------------------------------------------------------例子
--查询表xxxx_detail的信息,并按照xxxx_price升序排列前2条。SELECT * from xxxx_detail order by xxxx_price limit 2;
--将表xxx_detail按照xxxx_price升序排序后,输出从第3行开始的3行数据。SELECT xxxx_id,xxxx_price from xxxx_detail order by xxxx_price limit 3 offset 2;


默认对数据进行升序排序,如果降序排序,需要使用desc关键字。

order by默认要求带limit数据行数限制,没有limit会返回报错。


10. DISTRIBUTE BY哈希分片


------------------------------------------------------------------------------例子
--查询表xxxx_detail中的列region值并按照region值进行哈希分片。SELECT region from xxxx_detail distribute by region;--等价于如下语句。SELECT region as r from xxxx_detail distribute by region;SELECT region as r from xxxx_detail distribute by r;


distribute by控制Map(读数据)的输出在Reducer中是如何划分的,如果不希望Reducer的内容存在重叠,或需要对同一分组的数据一起处理,可以使用distribute by来保证同组数据分发到同一个Reducer中。


11. SORT BY局部排序


------------------------------------------------------------------------------例子
--查询表xxxx_detail中的列region和xxxx_price的值并按照region值进行哈希分片,然后按照xxxx_price对哈希分片结果进行局部升序排序。SELECT region,xxxx_price from xxxx_detail distribute by region sort by xxxx_price;
--查询表xxxx_detail中的列region和xxxx_price的值并按照region值进行哈希分片,然后按照xxxx_price对哈希分片结果进行局部降序排序。SELECT region,xxxx_price from xxxx_detail distribute by region sort by xxxx_price desc;
--如果sort by语句前没有distribute by,sort by会对每个Reduce中的数据进行局部排序。SELECT region,xxxx_price from xxxx_detail sort by xxxx_price desc;


sort by默认对数据进行升序排序,如果降序排序,需要使用desc关键字。

如果sort by语句前有distribute by,sort by会对distribute by的结果按照指定的列进行排序。


12. LIMIT限制输出行数


SELECT * FROM xxxxx.xxxx_xxxx_xxxxWHERE ds = 20240520LIMIT 100;


limit 中的number是常数,用于限制输出行数,取值范围为int32位取值范围。


  • 子查询


1. 基础子查询



--格式1select <select_expr> from (<select_statement>) [<sq_alias_name>];
--格式2select (<select_statement>) from <table_name>;


普通查询操作的对象是目标表,但是查询的对象也可以是另一个select语句,这种查询为子查询。在from子句中,子查询可以被当作一张表,与其他表或子查询进行join操作。


2. IN SUBQUERY



--in subquery与left semi join用法类似--格式一select<select_expr1>from<table_name1>where<select_expr2>  in(select<select_expr3>from<table_name2>);--等效于leftsemijoin如下语句。select<select_expr1>from<table_name1><alias_name1>leftsemijoin<table_name2><alias_name2>  on<alias_name1>.<select_expr2>=<alias_name2>.<select_expr3>;
--格式二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>);
------------------------------------------------------------------------------例子set odps.sql.allow.fullscan=true;select * from xxxx_detail where xxxx_price in (select xxxx_price from shop);
set odps.sql.allow.fullscan=true;select * from xxxx_detail where xxxx_price   in (select xxxx_price from shop where xxxx_id = shop.xxxx_id);


select_expr1:必填。格式为col1_name, col2_name, 正则表达式,...,表示待查询的普通列、分区列或正则表达式。

table_name1、table_name2:必填。表的名称。

select_expr2、select_expr3:必填。表示table_name1和table_name2互相映射的列名。

col_name:必填。表的列名。


3. NOT IN SUBQUERY



--如果查询目标表的指定列名中有任意一行为NULL,则not in表达式值为NULL,导致where条件不成立,无数据返回select <select_expr1> from <table_name1> where <select_expr2> not in (select <select_expr2> from <table_name2>);--等效于left anti join如下语句。select <select_expr1> from <table_name1> <alias_name1>   left anti join <table_name2> <alias_name2> on <alias_name1>.<select_expr1> = <alias_name2>.<select_expr2>;
------------------------------------------------------------------------------例子--创建一张新表shop1并追加数据。create table shop1 as select xxxx_name,xxxx_id,xxxx_price from xxxx_detail;insert into shop1 values ('s8','c1',100.1);select * from shop1 where xxxx_name not in (select xxxx_name from xxxx_detail);
set odps.sql.allow.fullscan=true;select * from shop1 where xxxx_name not in (select xxxx_name from xxxx_detail where xxxx_id = shop1.xxxx_id);


select_expr1:必填。格式为col1_name, col2_name, 正则表达式,...,表示待查询的普通列、分区列或正则表达式。

table_name1、table_name2:必填。表的名称。

select_expr2、select_expr3:必填。表示table_name1和table_name2互相映射的列名。

col_name:必填。表的列名。


4. EXISTS SUBQUERY


--使用exists subquery时,当子查询中有至少一行数据时,返回True,否则返回False。select <select_expr> from <table_name1> where exists    (select <select_expr> from <table_name2>     where <table_name2_colname> = <table_name1>.<colname>   );
------------------------------------------------------------------------------例子set odps.sql.allow.fullscan=true;select * from xxxx_detail where exists (select * from shop where customer_id = xxxx_detail.xxxx_id);--等效于以下语句。select * from xxxx_detail a left semi join shop b on a.xxxx_id = b.xxxx_id;


select_expr:必填。格式为col1_name, col2_name, 正则表达式,...,表示待查询的普通列、分区列或正则表达式。

table_name1、table_name2:必填。表的名称。

col_name:必填。表的列名。


5. NOT EXISTS SUBQUERY



--当子查询中无数据时,返回True,否则返回Falseselect <select_expr> from <table_name1> where not exists     (select <select_expr> from <table_name2> where <table_name2_colname> = <table_name1>.<colname>);
------------------------------------------------------------------------------例子set odps.sql.allow.fullscan=true;select * from xxxx_detail where not exists (select * from shop where xxxx_name = xxxx_detail.xxxx_name);--等效于以下语句。select * from xxxx_detail a left anti join shop b on a.shop_name = b.xxxx_name;


select_expr:必填。格式为col1_name, col2_name, 正则表达式,...,表示待查询的普通列、分区列或正则表达式。

table_name1、table_name2:必填。表的名称。

col_name:必填。表的列名。


6. SCALAR SUBQUERY



--当子查询的输出结果为单行单列时,可以做为标量使用,即可以参与标量运算。select <select_expr> from <table_name1> where   (<select count(*) from <table_name2> where <table_name2_colname> = <table_name1>.<colname>)   <标量运算符> <scalar_value>;
------------------------------------------------------------------------------例子set odps.sql.allow.fullscan=true;select * from shop where   (select count(*) from xxxx_detail where xxxx_detail.xxxx_name = shop.xxxx_name) >= 1;


select_expr:必填。格式为col1_name, col2_name, 正则表达式。

table_name1、table_name2:必填。表的名称。

col_name:必填。表的列名。

标量运算符:必填。例如大于(>)、小于(<)、等于(=)。

scalar_value:必填。标量值


  • 交集,并集和补集


1. 交集



--取交集不去重。<select_statement1> intersect all <select_statement2>;--取交集并去重。intersect效果等同于intersect distinct。<select_statement1> intersect [distinct] <select_statement2>;
------------------------------------------------------------------------------例子select * from values (1, 2), (1, 2), (3, 4), (5, 6) t(a, b) intersect all select * from values (1, 2), (1, 2), (3, 4), (5, 7) t(a, b);--结果+------------+------------+| a          | b          |+------------+------------+| 1          | 2          || 3          | 4          |+------------+------------+

select_statement1、select_statement2:必填。

distinct:可选。对两个数据集取交集的结果去重。


2. 并集


--取并集不去重。<select_statement1> union all <select_statement2>;--取并集并去重。<select_statement1> union [distinct] <select_statement2>;
------------------------------------------------------------------------------例子select * from values (1, 2), (1, 2), (3, 4) t(a, b) union all select * from values (1, 2), (1, 4) t(a, b);--结果+------------+------------+| a          | b          |+------------+------------+| 1          | 2          || 1          | 2          || 3          | 4          || 1          | 2          || 1          | 4          |+------------+------------+


select_statement1、select_statement2:必填。select语句。

distinct:可选。对两个数据集取并集的结果去重。


3. 补集


--取补集不去重。<select_statement1> except all <select_statement2>;<select_statement1> minus all <select_statement2>;--取补集并去重。<select_statement1> except [distinct] <select_statement2>;<select_statement1> minus [distinct] <select_statement2>;
------------------------------------------------------------------------------例子select * from values (1, 2), (1, 2), (3, 4), (3, 4), (5, 6), (7, 8) t(a, b)except all select * from values (3, 4), (5, 6), (5, 6), (9, 10) t(a, b);--结果+------------+------------+| a          | b          |+------------+------------+| 1          | 2          || 1          | 2          || 3          | 4          || 7          | 8          |+------------+------------+


select_statement1、select_statement2:必填。select语句。

distinct:可选。对取补集的结果去重。

相关实践学习
基于MaxCompute的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps&nbsp;
相关文章
|
4月前
|
SQL 分布式计算 DataWorks
DataWorks产品使用合集之如何开发ODPS Spark任务
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
|
4月前
|
分布式计算 资源调度 Hadoop
Hadoop入门基础(五):Hadoop 常用 Shell 命令一网打尽,提升你的大数据技能!
Hadoop入门基础(五):Hadoop 常用 Shell 命令一网打尽,提升你的大数据技能!
|
3月前
|
SQL 分布式计算 大数据
代码编码原则和规范大数据开发
此文档详细规定了SQL代码的编写规范,包括代码的清晰度,执行效率,以及注释的必要性。它强调所有SQL关键字需统一使用大写或小写,并禁止使用select *操作。此外,还规定了代码头部的信息模板,字段排列方式,INSERT, SELECT子句的格式,运算符的使用,CASE语句编写规则,查询嵌套规范,表别名定义,以及SQL注释的添加方法。这些规则有助于提升代码的可读性和可维护性。
67 0
|
3月前
|
SQL 分布式计算 大数据
大数据开发SQL代码编码原则和规范
这段SQL编码原则强调代码的功能完整性、清晰度、执行效率及可读性,通过统一关键词大小写、缩进量以及禁止使用模糊操作如select *等手段提升代码质量。此外,SQL编码规范还详细规定了代码头部信息、字段与子句排列、运算符前后间隔、CASE语句编写、查询嵌套、表别名定义以及SQL注释的具体要求,确保代码的一致性和维护性。
111 0
|
4月前
|
SQL 存储 分布式计算
MaxCompute 入门:大数据处理的第一步
【8月更文第31天】在当今数字化转型的时代,企业和组织每天都在产生大量的数据。有效地管理和分析这些数据变得至关重要。阿里云的 MaxCompute(原名 ODPS)是一个用于处理海量数据的大规模分布式计算服务。它提供了强大的存储能力以及丰富的数据处理功能,让开发者能够快速构建数据仓库、实时报表系统、数据挖掘等应用。本文将介绍 MaxCompute 的基本概念、架构,并演示如何开始使用这一大数据处理平台。
700 0
|
4月前
|
数据可视化
Echarts数据可视化开发| 智慧数据平台
Echarts数据可视化开发| 智慧数据平台
|
4月前
|
数据可视化
Echarts数据可视化大屏开发| 大数据分析平台
Echarts数据可视化大屏开发| 大数据分析平台
|
4月前
|
分布式计算 大数据 Java
Scala 入门指南:从零开始的大数据开发
Scala 入门指南:从零开始的大数据开发
|
1月前
|
存储 分布式计算 数据挖掘
数据架构 ODPS 是什么?
数据架构 ODPS 是什么?
289 7
|
1月前
|
存储 分布式计算 大数据
大数据 优化数据读取
【11月更文挑战第4天】
44 2
下一篇
DataWorks