2013-01-23 96 views
0

我有一個特殊的數據環境,我需要以某種方式返回數據來填充表。MySQL IN()子句多個返回

這是我當前的查詢:

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>

但是我要處理的問題是,它必須返回單個列中的名稱或全部名稱,因爲該字段可以包含與所選原始編輯器一樣多的字段。

+0

'bs_board = 0'你的意思是'bs_board ='0''? –

+1

如果可以,請將表格標準化。你不應該在一個列中有多個值。 – Kermit

+0

@njk我不能改變列的類型,它總是保持''varchar'像'1; 2; 3'這樣的值。這就是爲什麼我在這裏發佈,以找到是否有辦法解析它現在的方式。是的,我應該有多個價值觀,它完全能夠以這種方式工作,謝謝。 – jfreak53

回答

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 

周圍有問題的其他方式,但你會排序順序,匹配和其他許多問題都有問題。最好的解決方案是添加一個表並將這個多值字段移動到該表中。

1

b_id IN (REPLACE(bs_board, ';', ','))將導致b_id IN ('1,2,6,7')這是b_id IN (1,2,6,7)這是你正在尋找的不同。

使其工作或者在執行查詢之前解析字符串或使用預準備語句。

+0

請您詳細說明一下嗎? – jfreak53

+0

「b_id IN('1,2,6,7')」將b_id與單個字符串值'1,2,6,7'進行比較,而「b_id IN(1,2,6,7)」將b_id與每個4值中的集合。 – slaakso

+0

這就是我的觀點,它必須保持這種方式。我如何解析這些值,這是我的問題,我無法弄清楚如何將它解析爲「1,2,3」來將其解析爲「1,2,3」 – jfreak53