SQL 正则表达式和字段
Posted
技术标签:
【中文标题】SQL 正则表达式和字段【英文标题】:SQL regex and field 【发布时间】:2013-06-09 05:32:35 【问题描述】:我想更改查询以返回 extra_fields
中的乘法值,如何更改正则表达式?我也不明白extra_fields
是什么——它是一个字段吗?如果是这样,为什么不使用 i.extra_fields
之类的表前缀调用它?
SELECT i.*,
CASE WHEN i.modified = 0 THEN i.created ELSE i.modified END AS lastChanged,
c.name AS categoryname,
c.id AS categoryid,
c.alias AS categoryalias,
c.params AS categoryparams
FROM #__k2_items AS i
LEFT JOIN #__k2_categories AS c ON c.id = i.catid
WHERE i.published = 1
AND i.access IN(1,1)
AND i.trash = 0
AND c.published = 1
AND c.access IN(1,1)
AND c.trash = 0
AND (i.publish_up = '0000-00-00 00:00:00'
OR i.publish_up <= '2013-06-12 22:45:19'
)
AND (i.publish_down = '0000-00-00 00:00:00'
OR i.publish_down >= '2013-06-12 22:45:19'
)
AND extra_fields REGEXP BINARY '(.*"id":"2","value":\["[^\"]*1[^\"]*","[^\"]*2[^\"]*","[^\"]*3[^\"]*"\].*)'
ORDER BY i.id DESC
【问题讨论】:
你试过转义正则表达式中的大括号吗? 这不是答案,而是评论 【参考方案1】:extra_fields
是#__k2_items
表的一列。表限定符可以省略,因为它在此查询中没有歧义。该列是 JSON 编码的。这是一种序列化格式,用于存储设计上不可搜索的信息。应用正则表达式可能有一天会奏效,但另一天会失败,因为不能保证 id
先于 value
(如您的示例所示)。
正确的方法
过滤此问题的正确方法是忽略 SQL 查询中的 extra_fields
条件,而是在结果集中进行评估。示例:
$rows = $db->loadObjectList('id');
foreach ($rows as $id => $row)
$extra_fields = json_decode($row->extra_fields);
if ($extra_fields->id != 2)
unset($rows[$id]);
捷径
如果您无法更改数据库布局(对于您希望保持可更新的扩展来说确实如此),您必须将条件一分为二,因为无法保证 em> 用于子字段的特定顺序。出于某种原因,value
的某一天可能会发生在之前id
。因此,将您的查询更改为
...
AND extra_fields LIKE '%"id":"2"%'
AND extra_fields REGEXP BINARY '"value":\[("[^\"]*[123][^\"]*",?)+\]'
【讨论】:
我更喜欢保留 sql 因为有分页。无论如何我想把这个 REGEXP BINARY '(.*"id":"2","value":["[^\"]*1[^\"]*","[^\"]*2 [^\"]*","[^\"]*3[^\"]*"].*)' 找到其中一个值而不是精确的短语 好吧,那么 K2 是错误的选择。正如我在回答中所说,序列化的字段按设计是不可搜索的。 更新了我的答案以使extra_fields
有点可搜索。【参考方案2】:
准备一个中间表来保存 extra_fields 的内容。每个 extra_fields 字段都会被转换成一系列记录。然后做一个连接。 创建触发器和 cronjob 以保持临时表同步。
另一种方法是在 Perl 中编写 UDF 来解码字段,但 AFAIK 它在 mysql 中不可索引。
使用外部搜索引擎超出范围。
【讨论】:
【参考方案3】:好的,我不想更改数据库结构,我得到了一些帮助并将正则表达式更改为AND extra_fields REGEXP BINARY '(.*"id":"2","value":\[("[^\"]*[123][^\"]*",?)+\].*)'
我得到了正确的结果
谢谢
【讨论】:
以上是关于SQL 正则表达式和字段的主要内容,如果未能解决你的问题,请参考以下文章
Oracle SQL 查询中的正则表达式 - 仅限数字和句点
以 7 位数字结尾的字段的 Big Query SQL 正则表达式