在MySql中从一个列中提取多个值

3
我注意到MySql拥有广泛的搜索能力,允许使用通配符和正则表达式。然而,我卡在了一个问题上,我尝试从单个字符串中提取多个值,这使得我的选择查询变得困难。
例如,如果我有文本“<span>Test</span> this <span>query</span>”,也许使用正则表达式可以找到并提取“Test”或“query”的值,但在我的情况下,我可能有n个这样的字符串需要提取。由于我不能在选择语句中定义n个列,这意味着我被卡住了。
是否有办法获得任何包含在span标签中的文本值列表(理想情况下由逗号分隔)?
换句话说,如果我运行此查询,我将得到“Test,query”作为spanlist的值:
select <insert logic here> as spanlist from HtmlPages ...

想法:对于每个HtmlPages记录,返回多个记录,而不是多个列(当然也不要使用逗号分隔列表,除非你真的有/需要)(换句话说,是一个规范化的结果集)。 - MatBailie
我可以,但我有理由将其制作成逗号分隔列表。生成的查询将被导出到CSV文件,并最终导入Excel文档。虽然缺少这一点,每个跨度内容都有多条记录比什么都没有要好。 - Neil
可能是重复问题:https://dev59.com/n2865IYBdhLWcg3wCp9A - Don
请恕我直言,我认为这不是重复的,因为它是找到两个单词的解决方案,而不是 n 个单词。 - Neil
为了公正起见,仅仅因为使用SQL来拆分字符串不是理想的,就不应该假设在另一个层面使用另一种语言是理想的。这会导致选择最小劣解,并且为了做出这个选择,OP需要知道SQL解决方案、它的成本和收益。 - MatBailie
我使用外部编辑器(UltraEdit)成功解决了自己的问题。如果没有更好的解决方案,我将回答自己的问题并标记为正确答案。我知道数据结构不是最理想的,但我无法重写mediawiki,所以只能接受现有的情况。 - Neil
4个回答

1

我很惊讶没有人建议使用EXTRACTVALUE(xml,'xpath'),我认为它完全符合您的要求,只需要一点技巧就可以在其中添加分隔符(默认情况下,“分隔符”是一个空格)。

SET @xml = '<html><span>Test</span> this <span>query</span>
    <span>etc</span><div><span>etc etc</span></div></html>';

SELECT 
    LEFT(spanlist,LENGTH(spanlist)-1) AS spanlist
FROM
    (SELECT 
        EXTRACTVALUE(REPLACE(@xml,'</span>',',</span>'),'//span') AS spanlist
    ) AS T
;

生成

+---------------------------+
| spanlist                  |
+---------------------------+
| Test, query, etc, etc etc |
+---------------------------+

抱歉这个答案可能对你来说太晚了,但希望能帮到下一个人。


虽然有点晚,但那仍然是一个很好的答案,我很感激你的努力。不幸的是,它现在对我没有帮助,但下次遇到类似的情况我会记住这个答案的。 - Neil

1
首先,你的数据结构很糟糕。最常见的数据库规则之一是“每个行列交叉点都包含来自适用域的一个值(且仅有一个值)”。这是开发数据结构时的基本规则之一。
正如你所看到的,没有可能编写静态选择语句返回可变数量的列。 如果你不想改变结构,最好的方法是获取原始文本,并在你喜欢的编程语言中进行后处理。

我同意,但问题仍然是一个好问题,也许需要不同的数据。 - Don
我以HTML为例,但实际上,我正在尝试从Mediawiki页面中提取类别。它们的格式都是[[Category:Category name]]。它们通常在一起,但最好能够提供逗号分隔的列表给我的老板,而不是一堆可能准确的维基代码。 - Neil
1
SQL是一种用于操作关系型数据集的语言。但这不是关系型数据集,最好的方法可能是导出标签并使用某些计算或Excel来给它们适当的格式。 - piotrpo

1

MySQL确实有一个正则表达式引擎,但它是在WHERE子句中实现的,而不是作为查询字段的一部分。因此,它不能用于拆分字符串。

我建议您需要使用另一种语言来完成这个任务。使用应用程序查询数据并在那里按需拆分,或编写一个小程序来完成它 - 在PHP中可能只需要几行代码

如果您真的想在MySQL中完成它,您可能可以编写一个函数来完成它 - 参见这个答案Can Mysql Split a column? - 但坦率地说,这不是MySQL(或SQL一般)的设计目的。您最好正常查询数据并在另一种语言中将其拆分成片段。

我提到PHP是因为MediaWiki是用它编写的,所以您应该能够运行PHP代码而无需安装任何新软件,但几乎任何语言都可以)。


-1

不幸的是,唯一可用的解决方案是使用第三方文本编辑器(如Ultraedit)并使用正则表达式删除标记。似乎无法使用MySql。

虽然这不是理想的解决方案。如果有人偶然发现了这个问题,并有一个允许我使用MySQL提取此信息的解决方案,无论是多行还是其他方式,我将非常乐意听取。

缺乏更好的解决方案,现在这将是我的答案。


Ultraedit不是最佳解决方案,您的问题被标记为MYSQL,并且此解决方案已作为评论发布,请删除。我的建议是使用while循环。 - user1613360

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接