Redshift - 如何使用一个 table 中的列作为 SIMILAR TO 中的模式
Redshift - How to use column in one table as pattern in SIMILAR TO
我有两个 table 的问题。一组 table 包含网址及其信息,另一组网址应按模式分组。
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 与列参数一起应用似乎不起作用。
谁能给我一些建议?
提前致谢。
你要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;
您 运行 要求编译正则表达式模式并且 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 上的外部工具或存储过程。在一个查询中获取模式并使用它发出第二个查询。
我有两个 table 的问题。一组 table 包含网址及其信息,另一组网址应按模式分组。
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 与列参数一起应用似乎不起作用。
谁能给我一些建议? 提前致谢。
你要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;
您 运行 要求编译正则表达式模式并且 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 上的外部工具或存储过程。在一个查询中获取模式并使用它发出第二个查询。