Presto (AWS Athena) 中的拆分和搜索逗号分隔列
Posted
技术标签:
【中文标题】Presto (AWS Athena) 中的拆分和搜索逗号分隔列【英文标题】:Split and search comma separated column in Presto (AWS Athena) 【发布时间】:2020-02-14 20:36:25 【问题描述】:我有下表my_table
,其中两列都是字符串-
+------------+-------------+
| user_id| code |
+------------+-------------+
| ABC123| yyy,123,333|
| John| xxx,USA,555|
| qwerty| 55A,AUS,666|
| Thomas| zzz,666,678|
+------------+-------------+
我需要获取在其code
列值中具有yyy
或666
的所有user_id
。我已经在在线 mysql 模拟上测试了以下查询,它工作正常,但它在 AWS Athena 中不起作用-
SELECT user_id FROM my_table WHERE CONCAT(",", code, ",") REGEXP ",(yyy|666),";
结果应该是-
+------------+
| user_id|
+------------+
| ABC123|
| qwerty|
| Thomas|
+------------+
【问题讨论】:
【参考方案1】:使用regexp_like
:
WHERE regexp_like(code, '(^|,)(xxx|yyy)(,|$)')
presto:default> SELECT regexp_like('yyy,123,333', '(^|,)(xxx|yyy)(,|$)');
_col0
-------
true
(1 row)
(在 Presto 322 中测试,也可以在 Athena 中使用)
对于“更明显正确”的方法,我建议使用 split
+ contains
,尽管这可能会降低性能。
【讨论】:
只是为了确认,我的查询应该是SELECT user_id FROM my_table WHERE regexp_like(code, '(^|,)(yyy|666)(,|$)');
吗?
效果很好,谢谢。另外,regexp_like
的工作速度是否比 split + contains 快?
我会这么认为。如果您的查询性能以 IO 为主,那么它不会更快。【参考方案2】:
MySQL 有一个内置函数:
select t.*
from t
where find_in_set('666', code) > 0 or find_in_set('yyy', code) > 0;
虽然此功能可用,但强烈建议您修复数据模型并且不要将列表存储在字符串中。这不是 SQLish 存储东西的方式。
【讨论】:
我实际上知道这种方法,但是如果我想为 50 个值执行find_in_set
怎么办 :( 另外,我知道此列不应该是字符串,但这不能更改因为它不在我的手中
@kev 。 . .然后你有 50 个比较。
你是对的,只是查询变得很大。另外,我很抱歉一开始就不清楚,但是虽然您的查询在 MySQL 中运行良好 - 就像我的问题一样 - 它在 Presto 中不起作用。【参考方案3】:
您可以使用 regexp_like() 函数来获取验证上述条件的列。这将为相应的列返回一个布尔值。然后可以使用 WHERE 子句过滤掉结果。
最终查询:
WITH dataset AS (
SELECT
user_id,
regexp_like(code, '(^|,)(666|yyy)(,|$)') AS code
FROM my_table
)
SELECT user_id from dataset where code=true
【讨论】:
以上是关于Presto (AWS Athena) 中的拆分和搜索逗号分隔列的主要内容,如果未能解决你的问题,请参考以下文章
AWS DMS:如何处理 Presto/Athena 中的 TIMESTAMP_MICROS parquet 字段
删除 Presto SQL 兼容数据库 (AWS Athena) 中数据中的双引号?