我知道这不是创建表格的好习惯,所以请先把这些东西放在一边。
我有一张桌子,比如桌子A和桌子B
Table A :
| ID | fk_tableB_ID | title
-------------------------
| 10 | 1,2 | title 1
| 11 | 3 | title 2
Table B :
| ID | category
---------------
| 1 | cat1
| 2 | cat2
| 3 | cat3
我尝试了这个查询:
SELECT
a.ID,
a.title,
(
SELECT
group_concat(b.category)
FROM
tableB B
WHERE
B.ID IN (a.fk_tableB_ID)
) as category
FROM
tableA a
它返回:
| ID | category | title
-----------------------
| 10 | cat1 | title1
| 11 | cat3 | title2
但这不是我想要的。我想要的是
| ID | category | title
-----------------------
| 10 | cat1,cat2 | title1
| 11 | cat3 | title2
请帮忙,什么是正确的mysql查询代码,以便我可以获得上面的表。 Thx提前
答案 0 :(得分:0)
更好的方法是在中间放一个叫做'a_has_category'的桌子
Table a :
| ID | title
---------------
| 10 | title 1
| 11 | title 2
Table category :
| ID | category
---------------
| 1 | cat1
| 2 | cat2
| 3 | cat3
Table a_has_Category :
| ID | fk_a | fk_category
---------------
| 1 | 10 | 1
| 2 | 10 | 1
| 3 | 11 | 2
然后使用几个INNER JOINS构建您的查询
SELECT a.title, B.category FROM a
INNER JOIN a_has_category
ON fk_a = a_ID
INNER JOIN category
ON fk_category = category_ID
返回结果后,使用PHP的IMPLODE函数将类别连接成一个带逗号的字符串。
答案 1 :(得分:0)
是的,如果您在一个单元格中存储多个值,那么它几乎是如何工作的。省去麻烦并设计你的表,这样每行只有一个fk_tableB_ID。您可以将值组合到您选择的编程语言中的一行,因为它在MySQL中是不可行的。
这样的事情对你有用:
Table A :
| ID | page_ID | fk_tableB_ID | title
-------------------------
| 7 | 10 | 1 | title 1
| 8 | 10 | 2 | title 1
| 9 | 11 | 3 | title 2
Table B :
| ID | category
---------------
| 1 | cat1
| 2 | cat2
| 3 | cat3
您的查询将大大简化:
SELECT
a.page_ID,
b.category,
a.title
FROM
table_a a
LEFT JOIN
table_b b
ON
a.fk_tableB_ID = b.ID
如果您碰巧使用PHP,请在那里进行组合。这应该有效:
$r = mysql_query('SELECT ... ');
$result = array();
while($row = mysql_fetch_assoc($r)) {
$result[$row['page_ID']]['title'] = $row['title'];
$result[$row['page_ID']]['categories'][] = $row['category'];
}
哪个应该是这样的:
Array
(
[10] => Array
(
[title] => title 1
[categories] => Array
(
[0] => cat1
[1] => cat2
)
)
[11] => Array
(
[title] => title_2
[categories] => Array
(
[0] => cat3
)
)
)
如果你想使用那个数组来构建一个类似于你的例子的表,你可以使用它:
echo "| ID | category | title\n";
echo "----------------------------------------\n";
foreach($array as $page_ID => $row) {
echo '| '.str_pad($page_ID, 7);
echo '| '.str_pad(implode(',', $row['categories']), 20);
echo '| '.$row['title']."\n";
}
哪个会输出:
| ID | category | title
----------------------------------------
| 10 | cat1,cat2 | title_1
| 11 | cat3 | title_2
这正是你想要的。当然你可能想要输出一个HTML表,但你明白了。
答案 2 :(得分:0)
我知道您不想听到这一点,但表格字段中的多个值不是一个好设计,特别是如果此字段引用另一个表格。
如果要创建多对多关系,则需要一个中间表:
Table A :
| ID | title
------------
| 10 | title 1
| 11 | title 2
Table B :
| ID | category
---------------
| 1 | cat1
| 2 | cat2
| 3 | cat3
Table A_B:
| fk_tableA_ID | fk_tableB_ID
-----------------------------
| 10 | 1
| 10 | 2
| 11 | 3
我不认为可以在单个查询中执行您想要的操作(可能在存储过程中),但让我们看看其他人提出的内容。
字段中只有一个值称为first normal form (1NF)。这是数据库优化的第一步。
答案 3 :(得分:0)
按照您尝试的方式执行此操作的问题是IN函数需要一个数组。如果你真的需要沿着这条路线走下去,你必须在字符串上运行一个函数来创建一个数组,然后在IN语句中使用它。
这里有一个例子http://forums.mysql.com/read.php?60,78776,242420#msg-242420
但我建议改为添加链接表。
答案 4 :(得分:0)
如前所述,在一列中有多个外键是糟糕的设计,你必须使用n:m表。 请参阅此表结构作为示例:(是的,我遗漏了一些索引:)
CREATE TABLE IF NOT EXISTS `a` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
INSERT INTO `a` (`id`, `title`) VALUES (1, 'first row'), (2, 'second row'), (3, 'third row'), (4, 'fourth row');
CREATE TABLE IF NOT EXISTS `ab` ( `a_id` int(11) NOT NULL, `b_id` int(11) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `ab` (`a_id`, `b_id`) VALUES (1, 1), (1, 2), (1, 4), (2, 5), (3, 5), (4, 6), (4, 5), (3, 6);
CREATE TABLE IF NOT EXISTS `b` ( `id` int(11) NOT NULL AUTO_INCREMENT, `category` varchar(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ;
INSERT INTO `b` (`id`, `category`) VALUES (1, 'Cat1'), (2, 'Cat2'), (3, 'Cat3'), (4, 'Cat4'), (5, 'Cat5'), (6, 'Cat6');
然后您可以使用此查询:
SELECT a.id, a.title, group_concat( b.category )
FROM a
LEFT JOIN ab ON a.id = ab.a_id
LEFT JOIN b ON b.id = ab.b_id
GROUP BY a.id;
导致:
id title group_concat(b.category)
1 first row Cat4,Cat1,Cat2
2 second row Cat5
3 third row Cat5,Cat6
4 fourth row Cat5,Cat6