2010-02-25 97 views
2

所以,我明白这些关系是如何在mysql中工作的,但我很难弄清楚它是如何在我的代码中实现的。PHP/MySQL - *对多关系

例如,假设我有3张桌子。

表1:用户 - 用户ID,用户名,用户城市

表2:类 - 类ID,类别名称

表3:user_categories - 用户ID,类别ID

如果我要为位于特定城市的每个用户查询数据库,并列出它们属于的所有类别......我该怎么做?我是否需要遍历结果并为每个用户执行单独的查询,然后列出结果?或者,是否有一些神奇的查询会返回多维数组?

我相信上面会多到很多,纠正我,如果我错了....

编辑在user_categories表中,用户可以包含超过1类,我m试图找出如何返回所有人

谢谢!

回答

0

您需要JOIN表格。

如果我要查询每个用户的数据库,这是在一个特定的城市,并一一列举出来与所有他们属于

SELECT * 
FROM users 
INNER JOIN user_categories 
    ON (user_id) 
INNER JOIN categories 
    ON (category_id) 
WHERE ... 
+0

但是,这将返回,用户所属的所有类别呢? – user281482 2010-02-25 18:48:57

0

类别您可以尝试:

SELECT u.user_id, u.username, u.user_city, c.category_id, c.category_name 
FROM users u 
INNER JOIN user_categories uc ON u.user_id = uc.user_id 
INNER JOIN categories c ON uc.category_id = c.category_id 
WHERE u.user_city = 'Cityname'; 

我还没有测试过,可能有更有效的方法来做,但它应该工作。

如果您不熟悉mysql中的连接,请检查this

+0

我熟悉连接...但我的问题是,如果用户有多个类别,这将加入什么?只是它发现的第一个? – user281482 2010-02-25 18:48:05

+0

这应该为与该用户关联的每个类别返回一行。 – 2010-02-25 18:50:50

2

你是绝对正确的,它是一个多对多的查询。 从我的理解,你正在寻找的是具有某种分层结果显示的能力,这意味着对于一个用户来说,他有一个所有类别的分配给他...

夫妇事情可以做: 选项1:查询用户表:

SELECT u.user_id, u.username, u.user_city WHERE city = 'somecity'; 

从结果来看,得到所有匹配的USER_ID的,把它们放在一个阵列。

array(1,3,4,5) 

然后通过加入2个表类别和user_categories,以及使所述阵列作为逗号在一个其中在分隔的列表执行的查询:

SELECT user_categories.user_id, categories.category_name 
FROM user_categories INNER JOIN categories ON user_categories.category_id = categories.category_id 
WHERE user_categories.user_id IN (1,3,4,5) 

这会给你用户的列表ID,类别名称,您可以在您的脚本中使用以前的结果来构建结果集

选项2:我的首选,使用MySQL的GROUP_CONCAT(http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat)。

SELECT users.user_id, users.user_name, GROUP_CONCAT(categories.category_name) AS categories 
FROM users 
INNER JOIN user_categories ON users.id = users_categories.user_id 
INNER JOIN categories ON user_categories.category_id = category.id 
WHERE user.user_city = 'somecity' 
GROUP BY user.user_id 

这将返回类似:

user_id  username  categories 
1    u1   cat1, cat2, cat3 
2    u2   cat1, cat3 

您可以通过在GROUP_CONCAT,使用隔板指定的分隔符。

+0

谢谢!选项2看起来不错...我会试试看! – user281482 2010-02-25 19:00:07