0

我有一个包含三个表的数据库:

Products
MaterialsProducts
Materials

表之间的关系是这样的:

Materials 1-* MaterialsProducts *-1 Products

我经常需要检索200 多种产品及其相关材料数据(从Materials表中)。

目前它是这样完成的:

SQL:选择所有相关产品
PHP:遍历选择的产品,调用数据库为每个产品选择
材料数据(为每个产品生成一个数据库调用!)

有没有办法同时选择所有相关产品及其材料数据?并且仍然让每个产品在结果中只占一行。

所以解决方案不应该是"SELECT * FROM products p, materialsproducts mp, materials m WHERE p.id = mp.productid AND m.id = mp.materialid WHERE x". (该 SELECT 将使每个产品在结果中占据多于一行。)

4

4 回答 4

0

像这样的查询将每个产品的材料数据压缩到一行中并不简单 - 所以我认为该计划不适合您。

我建议改为使用普通的 JOIN 查询(​​很像您在问题中提出并被拒绝的查询),然后使用 PHP 代码来处理单个产品在结果集中具有多行的情况,因为它是链接的到多种材料。

于 2013-04-15T08:40:40.823 回答
0

你可以left join用来获取你需要的所有数据

文档 在这里

您的查询有误

"SELECT * FROM `products` p LEFT JOIN `materialsproducts` mp on p.`id` = mp.`productid` LEFT JOIN `materials` m ON m.`id` = mp.`materialid` WHERE $whateveryouneed"

请记住不要将您限制WHERE为只有 1 个,ID否则您将需要更多查询。

UPDATED 如被问及

products has a 1-* relationship with both materialsproducts and typesproducts. materialsproducts has a *-1 relationship with materials. typesproducts has a *-1 relationship with types.

所以你可以通过left join这种方式进行如上的查询

SELECT * FROM `products` p
LEFT JOIN `materialsproducts` mp
ON p.`id` = mp.`productid` 
LEFT JOIN `materials` m
ON mp.`mp_field_id_here` = m.`m_field_id_here`  //here you need to change with actual field to compare
LEFT JOIN `typesproducts` tp
ON p.`id` = tp.`tp_field_id_here`  //here you need to change with actual field to compare
LEFT JOIN `types` t
ON tp.`tp_field_id_here` = t.`t_field_id_here`  //here you need to change with actual field to compare

然后您可以添加一个where语句以将结果限制为适合您的内容

WHERE WHATEVER_YOU_NEED

UPDATED AGAIN

将结果限制为仅提交一些文件,只需更改*为特定的内容

"SELECT p.`Product_Name`, m.`Material_1`, m.`Material_2, m.`Material_3`, t.`Type_1`, t.`Type_2` FROM .....

注意我假设您material 1, material 2, material 3material表中检索这就是我用作前缀的原因m。无论哪种方式,我都用作前缀ttype 1 and type 2因为我认为它们是type表格的文件,否则您可以根据需要更改它们。

于 2013-04-15T06:58:17.707 回答
0

尝试

SELECT p.*, mp.*,m.* 
FROM products p 
JOIN materials m ON p.id=m.prd_id 
JOIN materialsproducts mp ON m.mp_id=mp.id;
于 2013-04-15T06:58:37.350 回答
0

您可以使用GROUP_CONCAT将与同一产品相关的材料组合到一个列表中,同时按产品分组:

SELECT
  p.ProductID,
  p.ProductName,
  GROUP_CONCAT(m.MaterialName) AS Materials
FROM Products p
INNER JOIN MaterialsProducts mp ON p.ProductID  = mp.ProductID
INNER JOIN Materials          m ON m.MaterialID = mp.MaterialID
GROUP BY
  p.ProductID,
  p.ProductName
;
于 2013-04-15T10:51:01.623 回答