2

假设如下:

表“信息”:

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

表“目标”:

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

使用left join,我期待这样的事情:

 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

如何获得第三张表中显示的结果?谢谢

4

1 回答 1

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上查看。

但是,您可能最好规范化您的数据结构并将您的信息目标关系存储在单独的表中:

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),则需要rankInfoTargets.

于 2012-05-30T08:53:19.357 回答