[英]How to optimize this SQL query to filter on a longtext/JSON field
我有一个表格,其中有一列长文本类型,它以longtext
格式存储营养值。 以下是数据的示例:
[{"label":"N","value":0.1,"percent":10},{"label":"P","value":0.1,"percent":10},{"label":"K","value":0.1,"percent":10},{"label":"S","value":"","percent":""},{"label":"Ca","value":"","percent":""},{"label":"Mg","value":"","percent":""},{"label":"Zn","value":"","percent":""},{"label":"Mn","value":"","percent":""},{"label":"Cu","value":"","percent":""},{"label":"B","value":"","percent":""},{"label":"Al","value":"","percent":""},{"label":"Fe","value":"","percent":""},{"label":"Na","value":"","percent":""},{"label":"Mo","value":"","percent":""}]
目前,我正在从 Db 中提取所有记录,然后使用foreach
遍历每条记录并过滤掉那些没有 N、P 和 K 且具有非零/空字符串百分比值的记录。
foreach($record as $rec){
$nutrients = json_decode($rec->nutrients);
$nutrientTextArray = [];
foreach($nutrients as $n){
if(in_array($n->label, ['N', 'P', 'K'])){
if($n->percent != ''){
$nutrientTextArray[] = $n->percent;
} else {
$nutrientTextArray[] = 0;
}
} else {
if($n->percent != ''){
$nutrientTextArray[] = $n->percent . $n->label;
}
}
}
但是,遍历每条记录的所有营养素需要太长时间。 我尝试在 SQL 查询本身中进行通配符匹配以进行过滤,执行如下操作,
select * from products where nutrients like '%"label":"N"%"label":"P"%"label":"K"%';
但这并没有考虑到非零/空百分比方面。
如何将此查询修改为仅具有标签 N、P 和 K 的 select 记录,其中每种营养素都具有非零/空字符串百分比值?
规范化你的数据库
好吧,这不是您问题的真正答案,而是一种方法。
由于您的查询相当复杂,您可以将 json 数据拆分为适当的数据库数据(对其进行规范化),例如每个字段都在 db 中反映。 然后,您可以 go 进行常规查询,并将这些表连接在一起。
哈克一号
除此之外,更“hacky”且可能不太可靠的方法:更改您的 JSON 数据,例如“percent”直接在字符串中的“label”后面。 比您也可以在一个长通配符术语中查询那个。 但请注意:然后,您将依赖数据结构来获取结果,这是我一般不会建议的。
最好的,弯曲的
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.