0

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

这是我当前的查询:

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是一个varchar包含多个行ID的字段,如下所示:

1;2;6;17

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

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

4

2 回答 2

1

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

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

于 2013-01-23T21:37:05.873 回答
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'

该问题最正确的解决方案是规范化您的数据库。您当前的系统或在单个字段中存储多个值正是您不应该使用 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

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

于 2013-01-23T22:01:14.797 回答