2012-05-30 13 views
2

假設如下:MySQL:如果列包含多個ID,如何使用左連接獲取數據?

表 「信息」:

id | target_ids 
----|------------ 
1 | 2 
2 | 
3 | 4,1 
4 | 2,3,1 

表 「目標」:

id | value 
----|------------ 
1 | dog 
2 | cat 
3 | tiger 
4 | lion 

使用左加入,我期待這樣的事情:

id | target_ids | value 
----|--------------------- 
1 | 2   | cat 
2 |   | 
3 | 4,1  | lion,dog 
4 | 2,3,1  | cat,tiger,dog 

我已經嘗試這樣:

select info.*, targets.value from info left join targets on info.target_ids = targets.id 

我是在「值」列單值結果

id | target_ids | value 
----|--------------------- 
1 | 2   | cat 
2 |   | 
3 | 4,1  | lion 
4 | 2,3,1  | cat 

我怎樣才能得到結果,因爲它是顯示在第三表?由於

+0

我會說你的表格格式不正確。你的值不是原子的(見1NF)。無論如何:如果您不能更改表格,您可以從info-table中的數據和您的temp-table中爲聯接創建臨時表格。 – konqi

回答

5

你需要使用MySQL的FIND_IN_SET()功能作爲連接標準:

SELECT info.*, GROUP_CONCAT(targets.value) AS value 
FROM  info LEFT JOIN targets ON FIND_IN_SET(targets.id, info.target_ids) 
GROUP BY info.id 

看到它的sqlfiddle

然而,你可能是最好的normalise你的數據結構和您的信息 - 目標關係存儲在一個單獨的表:

CREATE TABLE InfoTargets (
    InfoID INT NOT NULL, 
    TargetID INT NOT NULL, 
    PRIMARY KEY (InfoID, TargetID), 
    FOREIGN KEY (InfoID) REFERENCES info (id), 
    FOREIGN KEY (TargetID) REFERENCES targets (id) 
); 

INSERT INTO InfoTargets VALUES 
    (1,2), 
    (3,4), (3,1), 
    (4,2), (4,3), (4,1); 

ALTER TABLE Info DROP COLUMN target_ids; 

然後,你會怎麼做:

SELECT info.id, 
     GROUP_CONCAT(targets.id) AS target_ids, 
     GROUP_CONCAT(targets.value) AS value 
FROM  InfoTargets 
    LEFT JOIN info ON InfoID = InfoTargets.InfoID 
    LEFT JOIN targets ON TargetID = InfoTargets.TargetID 
GROUP BY info.id 

如果訂單的目標很重要(並且每個info項目之間可能有所不同),則需要在InfoTargets中創建另一個rank列。