从管道分隔的字符串中获取多个id以从另一个表中获取concat数据

时间:2015-04-07 10:06:12

标签: sqlite

我有两个表,其中一个表将几个id作为管道分隔的字符串,另一个表示每个id的名称。我希望将这些名称作为单行字符串连接起来,并在名称之间加上\ n。

表格

的Id-表

|   StringIds   |

'1|2|3|4|5|4|1'

命名表

| StringId | String Name |

  1        'One'

  2        'Two'

  3        'Three'

  4        'Four'

  5        'Five' 

我尝试使用以下代码但没有取得任何成功:

SELECT GROUP_CONCAT(StringName || '\n')
FROM Names 
WHERE 
   StringId 
   IN
   (
      SELECT DISTINCT 
      GROUP_CONCAT(REPLACE(StringIds,'|',',')) 
      FROM Ids

) ORDER BY StringName ASC

预期输出:'一个'\ n'两个'\ n'三个'\ n'四个'\ n'五个'\ n

Fiddle

1 个答案:

答案 0 :(得分:1)

问题是,您使用过的子查询

  SELECT DISTINCT 
    group_concat(replace(StringIds,'|',',')) 
  FROM Ids

实际上会按预期返回字符串'1,2,3,...'而不是数字列表1,2,3,...

WHERE StringId IN ((SELECT...))不能用于字符串,它需要一个元素列表,字符串是一个元素。

因此,您必须查看字符串函数,并且可以使用INSTR(X,Y)函数来查找StringId。

但在这里我们必须注意,因为如果i.E.我们在哪里寻找 数字3然后我们会找到它:

1,2,3,4

但它也会在

中找到它
1,2,30,4

所以诀窍是将分隔符包装在查询字符串周围 以及要搜索的字符串。因此,如果我们要在',3,'中搜索',1,2,3,4,' 我们会按预期匹配,如果我们搜索',1,2,30,4,',那么我们将无法匹配,这也是预期的。所以这就是我们在查询中有这些奇怪的连接的原因:)

SELECT group_concat(StringName || '\n') as AllNames
FROM Names 
WHERE INSTR(
  (',' || (
    SELECT DISTINCT 
      group_concat(replace(StringIds,'|',',')) 
    FROM Ids
  ) || ','),
  (',' || StringId || ',')
) > 0
ORDER BY StringName ASC;

现在好了,如果我们考虑一下,并且因为我们正在搜索一个字符串, 我们不妨使用你的oringinal字符串 提前转换它:

SELECT group_concat(StringName || '\n') as AllNames
FROM Names 
WHERE INSTR(
  ('|' || (
    SELECT StringIds FROM Ids LIMIT 1
  ) || '|'),
  ('|' || StringId || '|')
) > 0
ORDER BY StringName ASC;

实际上我们还有很多方法可以做到这一点。让我使用LIKE比较而不是INSTR函数给你最后一个版本:

SELECT group_concat(StringName || '\n') as AllNames
FROM Names 
WHERE
  ('|' || (
    SELECT StringIds FROM Ids LIMIT 1
  ) || '|')
  LIKE
  ('%|' || StringId || '|%')
ORDER BY StringName ASC;

希望此链接有效,因此您可以Fiddle around here

<强>更新

如果您的Ids表中有更多条目,并且您想要打印出Ids表中每个条目的唯一名称,那么您必须转换查询:

SELECT
( SELECT group_concat(StringName || '\n')
  FROM Names 
  WHERE
    ('|' || (
      StringIds
    ) || '|')
    LIKE
    ('%|' || StringId || '|%')
  ORDER BY StringName ASC
 ) as AllNames FROM Ids

现在,这里的Ids是循环的外部表,对于每个条目执行子查询,返回AllNames值。