【问题标题】:Mysql get comma separated list of columnsMysql获取逗号分隔的列列表
【发布时间】:2023-04-06 19:17:01
【问题描述】:

我有一个产品配件的专栏,如下例:

表 1

ProductID    accessories
1            2,3  
2            1,4,5
3
4            1
5            2

这意味着对于 PRODUCT 2,它的配件产品 ID 为 1,4 和 5

我有下面的最终表 2,如下所示

表2

GRP     ProductID     accessories 
a       2             
b       3             
c       1             
d       4             
e       5 

所以实际上如果使用 UPDATE 它会是这样的

表2

UPDATE table t2
INNER JOIN table1 t1
On t2.ProductID = t1.ProductID
set t2.accessories = t1.accessories 

GRP     ProductID     accessories
a       2             1,4,5
b       3              
c       1             2,3
d       4             1
e       5             2

但我想根据 t2.ProductID 用 GRP 字符更改 t2.accessories 中的 productID,以便最终表看起来像这样。

表2

GRP     ProductID     accessories
a       2             c,d,e
b       3              
c       1             a,b
d       4             c
e       5             a

我真的很困惑如何正确地做到这一点,我可以使用 php 代码来处理这个问题,但是这需要很长时间,因为我有 100k 产品,因此我更喜欢使用一些 group_concat 或 concat_ws 来处理这个

并且一些 t2.accessories 可能已经被存储,因此它应该是不同的值,所以 table2 上没有重复的 t2.accessories

这是http://sqlfiddle.com/#!9/bfddf的表格

【问题讨论】:

  • 这将很难做到,因为您将不得不解析附件字符串以获取每个整数值。如果您完全可以更改数据库架构,则应尽量不要存储逗号分隔的列表。
  • 实际上我已经有 2m 行带有逗号分隔的附件。所以如果可以处理那就太好了
  • 希望有人知道怎么做,但以后尽量不要那样做。 Here 是关于这个话题的一个非常好的问题。
  • 更改数据库的结构。您应该使用多对多关系。
  • 所以您建议将逗号分隔字符串的值拆分到另一个表中?

标签: mysql sql group-concat concat-ws


【解决方案1】:

您应该修复您的数据结构以拥有一个联结表。不要将列表存储为字符串。 SQL 有一个非常好的存储列表的方法;它被称为表。不要将数字存储为字符串。 SQL 具有非常好的数字数据类型。它们的名称中不包含“char”。

有一种方法可以在数据库中做你想做的事,但你不能抱怨性能。正确地构建数据结构会更快。

执行连接的选择查询如下所示:

select t1.productid,
       group_concat(t2.productid order by find_in_set(t2.ProductId, t1.accessories))
from table1 t1 join
     table2 t2
     on find_in_set(t2.ProductId, t1.accessories) > 0
group by t1.productid;

但是,你真的应该修复你的数据结构。

【讨论】:

  • 谢谢,这几乎是正确的,这对我有用
    select t1.productid, group_concat(t2.GRP order by find_in_set(t2.GRP, t1.accessories)) from table1 t1 join table2 t2 on find_in_set(t2.ProductId, t1.accessories) > 0 group by t1.productid 只需将其更改为更新类似 UPDATE table2 t2 set t2.accessories = (select..
  • 我提供的表结构只是虚拟数据。我使用的表格结构正确
  • 如果您将逗号分隔的标识符列表存储为字符串,如何正确构建数据?如果你有不同的数据结构,你应该问一个新问题。
  • 我以为你指的是另一种结构。所以据我了解。在这种情况下。逗号分隔的附件列应该是整数?如果附件列包含字符,那么最好将它们一一存储在单独的表中?
  • @inventor 。 . .最好将它们存储在单独的表中 - 称为联结表 - 每个 ProductIdaccessory 一行。
【解决方案2】:

这如我所愿。

UPDATE table2 
INNER JOIN ( 
            select t1.productid, group_concat(t2.GRP order by find_in_set(t2.GRP, t1.accessories)) as test from table1 t1 
            join table2 t2 on find_in_set(t2.ProductId, t1.accessories) > 0 group by t1.productid
            ) as temp on table2.ProductId=temp.productid
set table2.accessories=temp.test

唯一的问题是,如果你有大量的行,它会花费很长时间

【讨论】:

    猜你喜欢
    • 2013-07-03
    • 1970-01-01
    • 1970-01-01
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    • 2015-01-01
    • 2020-09-03
    相关资源
    最近更新 更多