2

我有 2 个表格、项目和成员:

CREATE TABLE IF NOT EXISTS `items` (
`id` int(5) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`member` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS `members` (
  `id` int(5) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

例如,如果我在里面有一条记录items,例如

INSERT INTO  `test`.`items` (
`id` ,
`name` ,
`member`
)
VALUES (
NULL ,  'xxxx',  '1, 2, 3'
);

members

INSERT INTO `members` (`id`, `name`) VALUES
(1, 'asdf'),
(2, 'qwert'),
(3, 'uiop'),
(4, 'jkl;');

我想用类似的东西来显示items.member数据??members.name1#asdf, 2#qwert, 3#uiop

我试过以下查询,

SELECT items.id, items.name, GROUP_CONCAT(CONCAT_WS('#', members.id, members.name) ) as member

FROM `items` 
LEFT JOIN members AS members on (members.id = items.member)
WHERE items.id = 1

但结果并不像我预期的那样。还有其他方法可以通过一个调用查询显示数据吗?因为我使用的是PHP,所以现在我正在分解items.member并一一循环,以显示members.name.

4

2 回答 2

3

您可以考虑FIND_IN_SET()在您的加入条件中使用:

FROM items JOIN members ON FIND_IN_SET(members.id, items.member)

但是,请注意 的定义FIND_IN_SET()

字符串列表是由“<code>”字符分隔的子字符串组成的字符串。

因此,该items.member列不应包含任何空格(我想您可以使用FIND_IN_SET(members.id, REPLACE(items.member, ' ', ''))- 但随着数据库的增长,这将非常昂贵)。

确实,您应该 规范化您的架构:

CREATE TABLE memberItems (
  item_id   INT(5) NOT NULL,
  member_id INT(5) NOT NULL,
  FOREIGN KEY   item_id REFERENCES   items (id),
  FOREIGN KEY member_id REFERENCES members (id)
);

INSERT INTO memberItems
  (item_id, member_id)
SELECT items.id, members.id
FROM   items
  JOIN members ON FIND_IN_SET(members.id, REPLACE(items.member,' ',''))
;

ALTER TABLE items DROP member;

这既是索引友好的(因此可以非常有效地查询)并且让数据库强制执行引用完整性。然后你可以这样做:

FROM items JOIN memberItems ON memberItems.item_id = items.id
           JOIN members     ON members.id = memberItems.member_id

另请注意,GROUP_CONCAT()以这种方式将单独的记录组合成一个字符串通常是不明智的:您的应用程序应该准备好循环遍历结果集以获取每个成员。

于 2012-12-02T15:03:21.247 回答
0

请看一下这个样本:

SQLFIDDLE

您的查询似乎适用于您在问题中提到的内容...... :)

SELECT I.ID, I.ITEM,
GROUP_CONCAT(CONCAT("#",M.ID,
M.NAME, " ")) AS MEMB

FROM ITEMS AS I
LEFT JOIN MEMBERS AS M
ON M.ID = I.MID
WHERE i.id = 1
;

已编辑的答案 此查询对您不起作用,因为您的架构似乎没有任何完整性......或正确的引用。另外,您的会员 ID 用逗号分隔,在这个答案中被忽略了。

于 2012-12-02T15:13:27.073 回答