mysql FIND_IN_SET -由于值加倍而获得部分输出

ryevplcw  于 12个月前  发布在  Mysql
关注(0)|答案(2)|浏览(84)

表“skus”:
| 植物种ID|
| - -----|
| 一二三一二三一|
表“plant_species
| id|姓名|
| - -----|- -----|
| 一个|工厂1|
| 2|工厂2|
| 3|工厂3|
我的MySQL代码的相关部分:

...
GROUP_CONCAT(plant_species.name SEPARATOR ', ') as plant_species_names
...
LEFT JOIN plant_species 
       ON FIND_IN_SET(plant_species.id, skus.plant_species_ids) > 0

我得到的输出:

Plant 1,Plant 2,Plant 3

我需要得到的结果:

Plant 1,Plant 2,Plant 3, Plant 2,Plant 3,Plant 1

据我所知,它的行为就像我在使用DISTINCT时,我没有。
有什么办法吗?
编辑
以下是我的最终代码,供有同样问题的其他人使用:``

SELECT orders.id, orders.customer_id, orders.invoice_amount, orders.delivery_date, orders.delivery_time, GROUP_CONCAT(skus.name SEPARATOR ', ') as sku_name, orders.sku_ids as sku_ids, orders.sku_weights as sku_weights

FROM orders

JOIN json_table(concat('[',orders.sku_ids,']'), '$[*]' columns (id int path '$')) AS species_ids

LEFT JOIN skus on skus.id=species_ids.id
WHERE orders.id=10
GROUP BY orders.id;

``

p8h8hvxi

p8h8hvxi1#

一种更简单的方法是将ids列用括号括起来,然后使用json_table展开它,但我不确定如何将其作为左连接来执行。

select skus.id, GROUP_CONCAT(plant_species.name SEPARATOR ', ') as plant_species_names
from skus
join json_table(concat('[',skus.plant_species_ids,']'), '$[*]' columns (id int path '$')) as species_ids
left join plant_species on plant_species.id=species_ids.id
group by skus.id

fiddle
最初的select不会找到后面的重复id,因为join只比较skus行和plant_species行,而不是plant_species_ids中的单个id,find_in_set只会找到plant_species_ids中plant_species id的第一个示例。

taor4pac

taor4pac2#

如果你使用的是MySQL 8.0,你可以使用递归查询来解嵌套所有逗号分隔的“plant_species_ids”数据:

  • 基本步骤:通过计算逗号来计算字符串的长度
  • 递归步骤:使用SUBSTRING_INDEX并减少整数索引,在逗号中提取值,每一步一个

一旦索引达到0,就停止递归。然后,您可以将未嵌套的表与“plant_species”表连接,并应用聚合。

WITH RECURSIVE cte AS (
    SELECT plant_species_ids,
           '-1' AS element,
           CHAR_LENGTH(REGEXP_REPLACE(plant_species_ids, '[^,]', ''))+1 AS num_elements
    FROM skus
  
    UNION ALL
  
    SELECT plant_species_ids, 
           SUBSTRING_INDEX(SUBSTRING_INDEX(plant_species_ids, ',', num_elements), ',', -1),
           num_elements - 1
    FROM cte
    WHERE num_elements > 0
)
SELECT GROUP_CONCAT(ps.name ORDER BY cte.num_elements) AS plants
FROM       cte
INNER JOIN plant_species ps
        ON cte.element = ps.id
WHERE cte.element > 0

输出

| 植物|
| - -----|
| 工厂1、工厂2、工厂3、工厂2、工厂3、工厂1|
查看演示here
注意:一般情况下,最好不要将数据存储为逗号分隔的值,因为很难对此类数据应用数据操作,并且通常需要使用非常低效和丑陋的查询来处理它。

相关问题