MySql SELECT通过Spliting由||分隔的多个值

时间:2014-11-13 11:37:24

标签: mysql sql database

以下是SELECT查询

的结果集
mysql> select * from mytable where userid =242 ;

+--------+-----------------------------+------------+---------------------+---------------------+
| UserId | ActiveLinks                 | ModifiedBy | DateCreated         | DateModified        |
+--------+-----------------------------+------------+---------------------+---------------------+
|    242 | 1|2|4|6|9|15|22|33|43|57|58 |         66 | 2013-11-28 16:17:25 | 2013-11-28 16:17:25 |
+--------+-----------------------------+------------+---------------------+---------------------+

我希望通过拆分有效链接列并将其与以下格式的 UserId 相关联来SELECT记录,

例如

UserId   ActiveLinks 

242       1
242       2
242       4
242       6

任何人都可以帮我解决这个问题,截至目前我还没有想到什么。感谢

3 个答案:

答案 0 :(得分:1)

处理存储在数据中的列表很痛苦。在MySQL中,您可以使用substring_index()。以下应该做你想要的:

SELECT userid,
       substring_index(substring_index(l.ActiveLinks, '||', n.n), '|', -1) as link
FROM (select 1 as n union all select 2 union all select 3 union all select 4) n join
     ipadminuserslinks l
     on length(l.ActiveLinks) - length(replace(l.ActiveLinks, '||', '')) + 1 <= n.n
WHERE userid = 242;

第一个子查询生成一堆数字,您需要它们。您可能需要增加此列表的大小。

on子句将数字限制为列表中元素的数量。

你可能会说,这很复杂。使用联结表更容易,这是存储此类信息的关系方式。

答案 1 :(得分:0)

我会创建一个将分隔符作为参数的例程。 另一个in_var将是通讯线。

每次调用它时,它都会返回被调用的UserId的值集。 它基本上会使用一个基于'|'计数的循环(我们称之为管道) 通过这种方式,您可以实现@Gordon Linoff提出的解决方案,而无需知道您有多少活动链接。

答案 2 :(得分:0)

如果这只是与另一个表上的任何内容无关的值列表,我会以与Gordon相同的方式执行(如果需要,您可以交叉加入获取数字列表的子查询,以便轻松生成远更大范围的数字)。一个小问题是,如果数字的范围大于一行上的分隔值的数量,那么将重复最后一个值(在这种情况下使用DISTINCT轻松删除,当你想要的那里有重复值时更复杂保持)。

但是,如果分隔值列表与另一个表相关(例如是另一个表的id字段,那么你可以这样做: -

SELECT a.UserId, b.link_id
FROM mytable a
LEFT OUTER JOIN my_link_table b
ON FIND_IN_SET(b.link_id, replace(a.ActiveLinks, '|', ','))

即,使用FIND_IN_SET将表与相关表连接起来。在这种情况下转换任何|用作逗号分隔符的符号,以允许FIND_IN_SET工作。