我有一个特殊的数据环境,我需要以某种方式返回数据以填充表格。
这是我目前的查询:
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 1
和Board 2
。之后我可以处理在每个结果之间添加<br>
。
但我正在处理的问题是它必须在单个列中返回名称或所有名称,因为该字段可以包含与原始编辑器一样多的名称。
答案 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
还有其他方法可以解决问题,但是排序顺序,匹配和其他许多问题都会遇到问题。最好的解决方案是添加一个表并将该多值字段移动到该表。