2014-06-26 61 views
0

我有兩個表項,條件與下面分貝結構在MySQL數據庫所需的輸出需要查詢

ITEM => 
    ID - INTEGER 
    ITEM_NAME - VARCHAR 

CONDITION => 
    CID - INTEGER 
    COND_NAME - VARCHAR 
    ITEM_ARRAY - VARCHAR (Stores all ITEM ID's separated by space 
         like: 1 5 9 17 18 

CID COND_NAME IEM_ARRAY 

1 C1   1 5 9 

2 C2   9 17 18 

3 C3   3 7 11 

在我的前端部位應用中,我們已經給出選項,用戶可以選擇基於一個或多個項目我們必須簡短列出建議的項目

爲此,我們創建了一個ITEM_ARRAY列,它將相關ITEMS的信息按數組分隔。

我需要一個查詢來根據CONDITION表的相關ITEMS列出ITEM表中的所有ITEM_NAME。例如,如果用戶選擇1和9,那麼我們必須顯示ITEM ID(5 17 18)及其相應的ITEM NAME。喜歡這個。

ID | ITEM_NAME 
---+----------- 
5 | SOME ITEM1 
17 | SOME ITEM2 
18 | SOME ITEM3 

我試着寫一個查詢

SELECT SUBSTRING(s.ITEM,2, LENGTH(s.ITEM)) 
FROM (SELECT REPLACE(ITEM_ARRAY," ",",") as ITEM 
     FROM `CONDITION` 
     WHERE ITEM like "% 1 5 %") s 

上面的查詢顯示我的所有相關ITEM_ARRAY從條件表列表中,如果用戶選擇1到5,但如果用戶選擇像1一些不同的值, 9或1,17,18類ITEMS然後我的查詢無法列出相關項目。

我如何獲得所有相關的值。我們可以自由地對錶結構進行一些更改,而不會有數據冗餘。

請提出寶貴的建議,以解決問題。如果觸發器等其他概念可以幫助我們,請引導我。

回答

1

我覺得你最好的選擇是重新設計的CONDITION表所以它沒有單個ITEM ARRAY中的所有ITEM ID - 您應該有一個而不是每個ITEM ID的行。在這種情況下,你應該正常化的數據位,例如:

CREATE TABLE cond (
CID INT PRIMARY KEY AUTO_INCREMENT, 
COND_NAME VARCHAR(128)); 

CREATE TABLE condition_items (
CID INT, 
ITEM_ID INT); 

INSERT INTO cond VALUES (1,'C1'); 
INSERT INTO condition_items VALUES (1,1),(1,5),(1,9); 

INSERT INTO cond VALUES(2,'C2'); 
INSERT INTO condition_items VALUES (2,9),(2,17),(2,18); 

如果你正使用InnoDB,那麼你可以使用外鍵強制執行的完整性:

ALTER TABLE condition_items ADD FOREIGN KEY (CID) REFERENCES cond (CID); 

這將允許非常簡單連接來在表格之間執行。

SELECT item_id,item_name 
FROM cond 
JOIN condition_items USING (CID) 
JOIN item ON (item.id=condition_items.item_id) 
WHERE cond_name="C2"; 

請注意,您應該避免使用CONDITION作爲表名,因爲它是保留字。

+0

感謝您回答vhu上面的結構更改在select語句中發生了一些小改動後爲我工作,即SELECT ITEM_ID FROM'condition_items' C2 WHERE C2.CID IN(SELECT DISTINCT c.CID as CID FROM'condition_items' c WHERE ITEM_ID IN(5 ,9,17))。感謝您的幫助。 – user3770778

0

如果你可以改變你的表格結構,你應該將ITEM_ARRAY移動到它自己的表格中。

COND_ITEM => 
    COND_ID => INTEGER (foreign key to CONDITION table) 
    ITEM_ID => INTEGER (foreign key to ITEM table) 

然後你就可以使用查詢:

SELECT ID, ITEM_NAME 
FROM ITEM 
WHERE ID IN (
SELECT ITEM_ID 
    FROM COND_ITEM 
    WHERE COND_ID IN (
     SELECT COND_ID 
     FROM COND_ITEM 
     WHERE ITEM_ID IN (1, 9) 
    ) AND ITEM_ID NOT IN (1, 9) 
) 

或JOIN:

SELECT DISTINCT i.ID, i.ITEM_NAME 
FROM ITEM AS i 
JOIN COND_ITEM AS ci1 ON ci1.ITEM_ID = i.ID 
JOIN COND_ITEM AS ci2 ON ci1.COND_ID = ci2.COND_ID 
WHERE ci1.ITEM_ID NOT IN (1, 9) 
AND ci2.ITEM_ID IN (1, 9) 

DEMO

+0

感謝您回答Barmar。 – user3770778