赞
踩
前言
经常用不会忘记的,我这就不再赘述了
函数名 | 函数功能 | 函数定义 |
CHAR_MATCHCOUNT | 返回str1中有多少个字符出现在str2中 | bigint char_matchcount(string str1, string str2) |
将给定ASCII码ascii转换成字符 | string chr(bigint ascii) | |
CONCAT | 连接字符串 | string concat(string a, string b...) |
KEYVALUE | 返回key-value对中key所对应的value | KEYVALUE(STRING srcStr,STRING split1,STRING split2, STRING key) KEYVALUE(STRING srcStr, STRING key) //split1 = ";",split2 = ":" |
REGEXP_REPLACE | 字符串替换 | string regexp_replace(string source, string pattern, string replace_string[, bigint occurrence]) |
SPLIT_PART | 根据分隔符拆分字符串 | string split_part(string str, string separator, bigint start[, bigint end])) |
SUBSTR | 返回字符串指定位置指定长度的的子串。字符串替换 | string substr(string str, bigint start_position[, bigint length]) |
函数声明:
bigint char_matchcount(string str1, string str2)
用途:用于计算str1中有多少个字符出现在str2中。
参数说明:
返回值:Bigint类型。任一输入为NULL返回NULL。
示例:
- char_matchcount('abd','aabc') = 2
- -- str1中得两个字符串'a', 'b'在str2中出现过
函数声明:
bigint find_in_set(string <str1>, string <str2>)
用途: 查找字符串str1在以逗号(,)分隔的字符串str2中的位置,从1开始计数
参数说明:
返回值说明: 返回BIGINT类型。返回规则如下:
示例1:查找字符串ab在字符串abc,hello,ab,c中的位置。命令示例如下。
- select find_in_set('ab', 'abc,hello,ab,c');
- --返回3
备注:判断是否存在时场景,只需要设置返回值>0即可
在ODPS中,可以通过自身的JOIN操作来实现列转行的操作。具体步骤如下:
假设有一个表t1,包含三列id、name、value,如下所示:
id | name | value |
1 | A | value1 |
1 | A | value2 |
1 | A | value3 |
2 | B | value2 |
2 | B | value3 |
3 | C | value1 |
3 | C | value2 |
3 | C | value3 |
现在需要将value列中的值转为一行,可以使用自身的JOIN操作来实现,如下所示:
- SELECT
- t1.id,
- t1.name,
- t2.value
- FROM
- t1
- JOIN
- t1 t2
- ON
- t1.id = t2.id
- WHERE
- t1.value = 'value1'
- AND t2.value = 'value2';
执行以上SQL语句后,可以得到以下结果:
id | name | value |
1 | A | value2 |
3 | C | value2 |
在结果表中,只保留了满足条件的数据,即t1表中value列为'value1'且t2表中value列为'value2'的行。通过自身JOIN操作,将满足条件的数据连接到一起。
需要注意的是,自身JOIN操作会产生笛卡尔积,因此在实际使用时需要根据实际情况添加适当的筛选条件(例如WHERE子句),以保证结果的准确性。
将colname指定的列值聚合为一个数组 (此函数为MaxCompute 2.0扩展函数)
array collect_list(<colname>)
返回ARRAY类型。colname值为NULL时,该行不参与计算。
返回将参数中的所有字符串或ARRAY数组中的元素按照指定的分隔符连接在一起的结果。此函数为MaxCompute 2.0扩展函数。
- string concat_ws(string <separator>, string <str1>, string <str2>[,...])
- string concat_ws(string <separator>, array<string> <a>)
用COLLECT_LIST和CONCAT_WS函数实现行转列的示例:
- SELECT
- id,
- CONCAT_WS(',', COLLECT_LIST(value)) AS merged_col
- FROM
- t
- GROUP BY
- id;
在这个示例中,我们使用COLLECT_LIST函数将每个id对应的value列的值收集为一个数组。然后,我们使用CONCAT_WS函数将数组中的值连接成一个字符串,使用逗号作为分隔符。
执行上述查询后,将得到以上所示的结果。
可以看到,我们成功地将每个id对应的所有值合并为一个列,并按id进行了分组。
需要注意的是,行转列的结果将依赖于原始数据的分组情况。在上述示例中,我们按id进行了分组,因此每个id对应的值被合并为一个单独的字符串。
如果想要将多个列转换为一列,只需在CONCAT_WS函数中添加需要合并的列即可。
用指定的separator做分隔符,连接colname中的值。
命令格式
string wm_concat(string <separator>, string <colname>)
参数说明
假设有一个表student_scores,结构如下:
- | student_id | subject | score |
- |------------|---------|-------|
- | 1 | Math | 90 |
- | 1 | English | 85 |
- | 2 | Math | 75 |
- | 2 | English | 80 |
我们想要将每个学生的所有科目和分数合并为一个字符串,可以使用以下SQL查询:
- 1SELECT
- 2 student_id,
- 3 WM_CONCAT(',', subject) AS subjects,
- 4 WM_CONCAT(',', CAST(score AS STRING)) AS scores
- 5FROM
- 6 student_scores
- 7GROUP BY
- 8 student_id;
执行上述查询后,你将得到每个student_id对应的所有subject和score,合并成一个以逗号分隔的字符串。示例如下:
- | student_id | subjects | scores |
- |------------|----------------|--------|
- | 1 | Math,English | 90,85 |
- | 2 | Math,English | 75,80 |
请注意,WM_CONCAT函数的参数是要连接的字段,以及用作分隔符的字符串(在这个例子中是逗号)。由于WM_CONCAT只接受字符串类型,因此需要将数值类型的score转换为字符串类型,这里使用了CAST函数。
这种方法有个潜在的问题:默认情况下,WM_CONCAT函数不保证元素的顺序。如果顺序对你的应用很重要,你可能需要考虑其他方法来确保顺序,比如使用ROW_NUMBER()函数先对数据进行排序。
备注:wm_concat无法作用于数组
DPS中的Lateral View语句用于将一个表的列(含分隔符)展开成多行,通常用于处理数组或集合类型的列
- SELECT ...
- FROM table
- LATERAL VIEW [OUTER] udtf(expression) AS alias_column
假设已有一张表pageAds,它有三列数据,第一列是pageid string,第二列是col1 array<int>,第三列是col2 array<string>,详细数据如下。
pageid | col1 | col2 |
front_page | [1, 2, 3] | [“a”, “b”, “c”] |
contact_page | [3, 4, 5] | [“d”, “e”, “f”] |
单个 Lateral View语句拆分col1。命令示例如下:
- select pageid, col1_new, col2 from pageAds lateral view explode(col1) adTable as col1_new;
-
- -- 返回结果如下:
- +--------------+------------+-------------+
- | pageid | col1_new | col2 |
- +--------------+------------+-------------+
- | front_page | 1 | ["a","b","c"] |
- | front_page | 2 | ["a","b","c"] |
- | front_page | 3 | ["a","b","c"] |
- | contact_page | 3 | ["d","e","f"] |
- | contact_page | 4 | ["d","e","f"] |
- | contact_page | 5 | ["d","e","f"] |
- +------------+------------+------------+
方式一:INNER JOIN 。。。基操忽略
方式二:
- --取交集不去重。
- <select_statement1> intersect all <select_statement2>;
- --取交集并去重。intersect效果等同于intersect distinct。
- <select_statement1> intersect [distinct] <select_statement2>;
- --取并集不去重。
- <select_statement1> union all <select_statement2>;
- --取并集并去重。
- <select_statement1> union [distinct] <select_statement2>;
- --取补集不去重。
- <select_statement1> except all <select_statement2>;
- <select_statement1> minus all <select_statement2>;
- --取补集并去重。
- <select_statement1> except [distinct] <select_statement2>;
- <select_statement1> minus [distinct] <select_statement2>;
说明 except和minus等效。
按照某一个字段分组后取某个分组的前N行
诉求:假设您有一个名为table_name的ODPS表,其中有一个字段为group_field,您可以按照group_field字段进行分组,并取每个分组的前200条数据
方式1: 可以使用ODPS的分区操作来按照某个字段进行分组,并使用LIMIT子句来限制每个分组的数据条数。
方式2: 使用ROW_NUMBER窗口函数
- SELECT *
- FROM (
- SELECT *,
- ROW_NUMBER() OVER(PARTITION BY group_field ORDER BY your_order_field) AS rn
- FROM table_name
- ) t
- WHERE rn <= 200
先利用ROW_NUMBER()函数为每个分组内的数据进行编号,然后再筛选出行号小于等于200的数据。
注意:请注意,这个方法适用于每个分组的数据量不大的情况,如果每个分组的数据量很大,可能会影响查询的性能。如果有大量数据需要处理,您可能需要考虑使用其他更高效的方法。
完整的文档,建议直接看官方文档:
https://help.aliyun-inc.com/internaldoc/detail/413657.html?spm=a2c1f.8259796.2.112.QbF0CL
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。