在MySQL中存储项目关系

时间:2017-01-16 19:31:36

标签: mysql database

背景

我希望能够在MySQL数据库中存储产品之间的复杂关系。

我目前有两张桌子。第一个是产品清单:

ID | sku | division | retired

第二个表是关系表

ID | prod1 | relation | prod2 

理念是prod2relationprod

示例行

产品表:

1 | lamp | household  | false
2 | lamp-short | household  | false
3 | chair| household | false
4 | desk | household | false
5 | desk-realwood | household | false
6 | desk-extratall | household | false
6 | couch | household | false

关系表:

1 | 1 | child | 2   <- short lamp is child of lamp
2 | 4 | child | 5   <- real wood desk is child of desk
2 | 4 | child | 6   <- extra tall desk is child of desk

然后在lamp的单个产品页面上,我想要一个&#34;相关产品&#34;盒子,所以我需要拉入所有相关产品。所以我需要一个SQL查询,给定productsproduct_relations的表名以及当前产品的ID,可以拉入products表中的所有行与当前产品有关。

IE,如果我正在查看lamp,我需要提取lamp-short

我想我需要使用JOIN,但是当我尝试过它时,我无法使用它。

SELECT *
FROM `products`
INNER JOIN `product_relations` on products.id = ( product_relations.prod2 WHERE product_relations.prod1 = 1 )

5被提供给查询。

问题

如果我知道当前产品的ID,我将如何编写查询以获取所有相关产品?

3 个答案:

答案 0 :(得分:2)

如果你想获得相关产品sku,并且它与原始产品的关系是sku,你可以使用:

SELECT rp.sku, r.relation
FROM product p
    INNER JOIN relations r ON p.id = r.prod1
    INNER JOIN product rp on r.prod2 = rp.id
WHERE p.sku = '<original sku>'

如果您使用原始产品的ID进行搜索,可以缩短此时间,因为您不需要上面的p别名表:

SELECT rp.sku, r.relation
FROM relations r
    INNER JOIN product rp on r.prod2 = rp.id
WHERE r.prod1 = '<original product id>';

您可以添加到WHERE子句以按特定r.relation类型进行过滤,例如“Child”或您拥有的内容。

答案 1 :(得分:1)

如果他们是孩子:

SELECT *
FROM products a
JOIN product_relations b
ON a.id = b.prod1
WHERE a.id = product_id_to_find

如果你想要所有相关的:

SELECT *
FROM products a
JOIN product_relations b
ON a.id = b.prod1 OR a.id = b.prod2
WHERE a.id = product_id_to_find

答案 2 :(得分:0)

这些完全基于JNevill的答案。我现在在这里添加它们,并为我自己和其他人提供更详细的参考,现在我了解它是如何工作的。

/***********************************************************************/
/******** GET ALL PRODUCTS "related" TO PRODUCT 1 (AND REVERSE) ********/
/***********************************************************************/

SELECT *
FROM products
JOIN product_relations
ON products.id = product_relations.prod2
WHERE product_relations.prod1 = 1 OR product_relations.prod2 = 1 AND product_relations.relation = "related"



/***********************************************************************/
/**************** GET THE CHILD PRODUCTS OF PRODUCT 1 ******************/
/***********************************************************************/

SELECT *
FROM products
JOIN product_relations
ON products.id = product_relations.prod2
WHERE product_relations.prod1 = 1 AND product_relations.relation = "child"



/***********************************************************************/
/**************** GET THE PARENT PRODUCT OF PRODUCT 1 ******************/
/***********************************************************************/

SELECT *
FROM products
JOIN product_relations
ON products.id = product_relations.prod1
WHERE product_relations.prod2 = 1 AND product_relations.relation = "child"

通过翻转上面的查找机制,我们不必在child表中包含parentproduct_relations行。 child行适用于两者。

/***********************************************************************/
/******** GET THE SUCCESSOR (NEW VERSION) PRODUCT OF PRODUCT 1 *********/
/***********************************************************************/

SELECT *
FROM products
JOIN product_relations
ON products.id = product_relations.prod2
WHERE product_relations.prod1 = 1 AND product_relations.relation = "successor"

/***********************************************************************/
/******* GET THE PREDECESSOR (OLD VERSION) PRODUCT OF PRODUCT 1 ********/
/***********************************************************************/

SELECT *
FROM products
JOIN product_relations
ON products.id = product_relations.prod2
WHERE product_relations.prod1 = 1 AND product_relations.relation = "predecessor"