Redshift - 如何使用一个表中的列作为 SIMILAR TO 中的模式

Posted

技术标签:

【中文标题】Redshift - 如何使用一个表中的列作为 SIMILAR TO 中的模式【英文标题】:Redshift - How to use column in one table as pattern in SIMILAR TO 【发布时间】:2021-08-10 14:21:25 【问题描述】:

我有两个表的问题。一个表包含 url 及其信息,另一组 url 应按模式分组。

Urls table:
------------------------------------------------
| url                                  | files |
| https://myurl1/test/one/es/main.html | 530   |
| https://myurl1/test/one/en/main.html | 530   |
| https://myurl1/test/one/ar/main.html | 530   |
------------------------------------------------

Urls patterns table:
---------------------------------------------
| group  | url_pattern                      |
| group1 | https://myurl1/test/one/(es|en)/%|
| group2 | https://myurl1/test/one/(ar)/%   |
---------------------------------------------

考虑到 url_patterns 每组只有一行,我已经尝试过类似的操作。

SELECT * FROM urls_table
WHERE url SIMILAR TO (SELECT MAX (url_pattern) FROM url_patterns WHERE group='group1')
LIMIT 10

这里的主要问题是,使用列参数应用 SIMILAR TO 似乎不起作用。

谁能给我一些建议? 提前致谢。

【问题讨论】:

您的解决方案从这里看起来很不错,您有问题吗?您的 Select MAX(...) 表示同一组可能有多个模式。要选择 URL 匹配任何模式的位置,请尝试 Select Distinct URL,files from urls_table, url_pattern where url Similar To url_pattern 你想要什么结果? 您好,第一个问题是似乎无法将类似于应用于子查询。这就是为什么我应用 MAX 来尝试只获取和字符串。 【参考方案1】:

您遇到了编译正则表达式模式的要求,并且 SIMILAR TO 是正则表达式的一个层。所以你试图做的事情是行不通的。我相信还有很多其他方法可以做到这一点。

I) 更改为 LIKE 模式匹配:LIKE 模式未预编译,因此可以使用动态模式。缺点是它们更受限制,但我认为你仍然可以做你想做的事。只需将您的模式更改为一组模式列(如果模式数量有限)并测试所有模式。不需要的模式可能只是一个永远无法匹配的值。绝对是蛮力破解。

II) 使用 SQL 更改为 LIKE 模式匹配以提供 OR 行为:在 url_pattern 列中有多个 LIKE 模式,用“|”分隔(例如)。然后使用 split_part 匹配每个子模式 - 有点复杂,可能很慢,但可以。像这样:

SELECT url
FROM urls_table
LEFT JOIN (SELECT split_part(pattern, '|', part_no::int) as pattern
              FROM url_patterns
              CROSS JOIN (SELECT row_number() over () as part_no FROM urls_table)
              WHERE "group" = 'group1'
             )
ON url LIKE pattern 
WHERE p.pattern IS NOT NULL;

您还需要更改模式字符串以使用更简单的 LIKE 格式并使用“|”多种可能性 - 例如:Group1 模式变为 'https://myurl1/test/one/es/%|https://myurl1/test/one/en/%'

III) 使用一些前端查询修改来查找组的模式并将其应用于查询,然后再将其发送到编译器。这可能是外部工具或 Redshift 上的存储过程。在一个查询中获取模式并使用它来发出第二个查询。

【讨论】:

【参考方案2】:

你想要exists吗?

SELECT u.*
FROM urls_table u
WHERE EXISTS (SELECT 1
              FROM url_patterns p
              WHERE u.url SIMILAR TO p.url_pattern AND
                    p.group = 'group1'
             )
LIMIT 10;

【讨论】:

这不会破坏 Redshift 的相关子查询限制吗?

以上是关于Redshift - 如何使用一个表中的列作为 SIMILAR TO 中的模式的主要内容,如果未能解决你的问题,请参考以下文章

使用大表连接更新 Amazon Redshift 中的列

Amazon Redshift:根据表中存在的列列表选择列

RedShift - 如何通过复合主键过滤表中的记录?

如何使用保存在表中的水平数据作为postgres中的列

如何使用特定表中的列作为我需要从中删除、插入或更新数据的表名

插入新创建的列