【问题标题】:String split of IDs and concat with names in MySQL在 MySQL 中将 ID 和 concat 与名称进行字符串拆分
【发布时间】:2017-02-27 08:33:49
【问题描述】:

我在 MySQL 中有以下表格

表 1:
c1 id
A1 3|5|2
A2 1|2
A3 3
A4 1|2|3|4|5
A5 2|4|1|3

表 2:
身份证号
1 AA
2 艾伯特
3 CDE
4 XXWQ
5年

我想将 tb1.ids = tb2.id 上的两个表作为拆分表 1 中的所有 id,然后替换为它们的名称,然后再次连接。

输出

3|5|2 -> CDE|Y|ABERT
1|2 -> AA|ABERT

我正在使用以下代码来拆分字符串。

CASE WHEN tb1.ids LIKE '%|%'THEN SUBSTRING_INDEX( `tb1.ids` , '|', 1 ) ELSE tb1.ids END AS id1,
CASE WHEN tb1.ids LIKE '%|%|%' THEN SUBSTRING_INDEX(SUBSTRING_INDEX( `tb1.ids` , '|', 2 ),'|',-1) WHEN tb1.ids LIKE '%|%' THEN SUBSTRING_INDEX( `tb1.ids` , '|', -1 )ELSE '' END AS id2,
CASE WHEN tb1.ids LIKE '%|%|%|%' THEN SUBSTRING_INDEX(SUBSTRING_INDEX( `tb1.ids` , '|', 3 ),'|',-1) WHEN tb1.ids LIKE '%|%|%' THEN SUBSTRING_INDEX( `tb1.ids` , '|', -1 ) ELSE '' END AS id3,
CASE WHEN tb1.ids LIKE '%|%|%|%|%' THEN SUBSTRING_INDEX(SUBSTRING_INDEX( `tb1.ids` , '|', 4 ),'|',-1) WHEN tb1.ids LIKE '%|%|%|%' THEN SUBSTRING_INDEX( `tb1.ids` , '|', -1 ) ELSE '' END AS id4,
CASE WHEN tb1.ids LIKE '%|%|%|%|%|%' THEN SUBSTRING_INDEX(SUBSTRING_INDEX( `tb1.ids` , '|', 5 ),'|',-1) WHEN tb1.ids LIKE '%|%|%|%|%' THEN SUBSTRING_INDEX( `tb1.ids` , '|', -1 ) ELSE '' END AS id5

【问题讨论】:

  • 永远不要在单个列中存储多个值。如果你这样做,你会遇到这样的问题。你能改变你的桌子设计吗?
  • 我没有对该数据库的写入权限。实际上,该列是特定旅行的多个目的地的行程。

标签: mysql stored-procedures split concatenation concat


【解决方案1】:

在表中存储分隔字段几乎总是一个坏主意。

但是,如果字段用逗号分隔,那么您可以使用 FIND_IN_SET 函数。如果绝望,您可以使用 REPLACE 在 FIND_IN_SET 函数中将分隔符更改为逗号:-

SELECT a.c1,
        a.ids,
        GROUP_CONCAT(b.name SEPARATOR '|')
FROM Table1 a
INNER JOIN Table2 b
ON FIND_IN_SET(b.id, REPLACE(a.ids, '|', ','))
GROUP BY a.c1,
        a.ids

【讨论】:

  • 这比我的解决方案还要好。
  • 谢谢,也谢谢你用逗号修正错别字。
  • 非常感谢你们俩 :)
  • @HarshRaval - 要订购名称,请使用GROUP_CONCAT(b.name ORDER BY FIND_IN_SET(b.id, REPLACE(a.ids, '|', ',')) SEPARATOR '|')
【解决方案2】:

如果您无法更改架构,您可以使用 LIKE 加入并将名称与 GROUP_CONCAT 组合:

select t1.c1, t1.ids, group_concat(t2.name separator '|') as names
from table1 t1
join table2 t2
  on concat('|', t1.ids, '|') like concat('%|', t2.id, '|%')
group by t1.c1, t1.ids

结果:

╔════╦═══════════╦═════════════════════╗
║ c1 ║    ids    ║        names        ║
╠════╬═══════════╬═════════════════════╣
║ A1 ║ 3|5|2     ║ CDE|ABERT|Y         ║
║ A2 ║ 1|2       ║ ABERT|AA            ║
║ A3 ║ 3         ║ CDE                 ║
║ A4 ║ 1|2|3|4|5 ║ CDE|Y|ABERT|AA|XXWQ ║
║ A5 ║ 2|4|1|3   ║ XXWQ|CDE|ABERT|AA   ║
╚════╩═══════════╩═════════════════════╝

演示:http://rextester.com/XHUP28245

如果您需要根据t1.ids对名称进行排序,一种可能的方法是使用 GROUP_CONCAT 中 ORDER BY 的 LOCATE 函数:

select t1.c1, t1.ids, group_concat(
    t2.name
    order by locate(concat('|', t2.id, '|'), concat('|', t1.ids, '|'))
    separator '|'
) as names
from table1 t1
join table2 t2
  on concat('|', t1.ids, '|') like concat('%|', t2.id, '|%')
group by t1.c1, t1.ids

结果:

╔════╦═══════════╦═════════════════════╗
║ c1 ║    ids    ║        names        ║
╠════╬═══════════╬═════════════════════╣
║ A1 ║ 3|5|2     ║ CDE|Y|ABERT         ║
║ A2 ║ 1|2       ║ AA|ABERT            ║
║ A3 ║ 3         ║ CDE                 ║
║ A4 ║ 1|2|3|4|5 ║ AA|ABERT|CDE|XXWQ|Y ║
║ A5 ║ 2|4|1|3   ║ ABERT|XXWQ|AA|CDE   ║
╚════╩═══════════╩═════════════════════╝

演示:http://rextester.com/WIUQ61685

【讨论】:

  • 为什么要使用 group by ,如果两个值相同,那么只会创建一条记录,如 A1 -> 3|2|5 A2 -> 3|2|5
  • 我已将查询更改为更有意义的内容。您没有在问题中发布确切的输出格式。
  • 为什么两个相同的 tb2.id 会给出混乱的名称,如 A1 -> 3|5|2 -> CDE|Y|ABERT A2 -> 3|5|2 -> Y|CDE|ABERT
  • 您可以通过 id 订购它们:group_concat(t2.name order by t2.id separator '|')。但是,如果您希望根据t1.ids 订购它们 - 这并不容易。
  • 有没有办法通过 t1.ids 的每个 id 获取订单?
猜你喜欢
  • 2013-02-03
  • 2020-12-30
  • 1970-01-01
  • 1970-01-01
  • 2020-11-15
  • 1970-01-01
  • 1970-01-01
  • 2018-02-22
相关资源
最近更新 更多