MySQL IN()子句多次返回

时间:2013-01-23 21:30:45

标签: mysql

我有一个特殊的数据环境,我需要以某种方式返回数据以填充表格。

这是我目前的查询:

SELECT 
  bs_id, 
  IF(bs_board = 0, 'All Boards', (SELECT b_name FROM certboards WHERE b_id IN (REPLACE(bs_board, ';', ',')))) AS board 
FROM boardsubs

正如您所看到的,我有一个if语句,然后是一个特殊的子语句。

我这样做的原因是字段bs_board是一个包含多个行ID的varchar字段,如下所示:

1;2;6;17

因此,类似的查询工作正常,但它只返回第一个匹配的b_name。我需要它来返回所有比赛。例如,在此1;2中,它应该在同一列中返回两个板Board 1Board 2。之后我可以处理在每个结果之间添加<br>

但我正在处理的问题是它必须在单个列中返回名称或所有名称,因为该字段可以包含与原始编辑器一样多的名称。

2 个答案:

答案 0 :(得分:1)

b_id IN (REPLACE(bs_board, ';', ','))将导致b_id IN ('1,2,6,7')与您正在寻找的b_id IN (1,2,6,7)不同。

使其工作要么在执行查询之前解析字符串,要么使用预准备语句。

答案 1 :(得分:1)

这不会像你认为的那样有效。

我们说bs_board'1;2;3'

在您的查询中,REPLACE(bs_board, ';', ',')将解析为'1,2,3',这是一个单字面字符串。这将使您的最终子查询:

SELECT b_name FROM certboards WHERE b_id IN ('1,2,3')

相当于:

SELECT b_name FROM certboards WHERE b_id = '1,2,3'

问题的最正确解决方案是normalize your database。您当前的系统或在单个字段中存储多个值正是您不应该对RDBMS执行的操作,这正是原因所在。数据库不是为处理这种字段而设计的。你 应该有一个单独的表,每个bs_board有一行,然后JOIN表。

这个问题没有很好的解决方案。这是一个基本的架构设计缺陷。最简单的方法是使用应用程序逻辑来修复它。首先你运行:

SELECT bs_id, bs_board FROM boardsubs

从那里解析应用程序逻辑中的bs_board字段并构建您想要运行的实际查询:

SELECT bs_id, 
  IF(bs_board = 0, 'All Boards', (SELECT b_name FROM certboards WHERE b_id IN (<InsertedStringHere>) AS board 
FROM boardsubs

还有其他方法可以解决问题,但是排序顺序,匹配和其他许多问题都会遇到问题。最好的解决方案是添加一个表并将该多值字段移动到该表。