2

次のことを前提としています。

テーブル「情報」:

 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

3番目の表に示されている結果を取得するにはどうすればよいですか?ありがとう

4

1 に答える 1

5

FIND_IN_SET()結合基準としてMySQLの関数を使用する必要があります。

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 に答える