![](/img/trans.png)
[英]Retrieve a complete list of all Categories, Sub Categories, Sub Sub Categories, etc. in only one SQL query
[英]SQL query to retrieve all products under some categories in Adjacency List Model
我有一个带有邻接列表方法的数据库来处理产品的分类,其中一个产品可以在许多类别下找到。 看看以下数据库布局:
cats
id parent title desc
1 0 top top level
2 1 Electronics
3 2 Gaming
4 2 Computers
5 4 Tablets
6 1 Food
7 3 Xbox
products
id title qty
1 ToshibaTV 5
2 I-PAD2 9
3 Laser Pen 24
4 Asus Notebook 5
cats_products
id product_id cat_id
1 2 3
2 2 5
3 1 2
4 3 2
5 4 4
在上面的例子中,我需要一个SQL查询,它能够检索电子类别中的所有产品及其任何级别的任何子类别(例如Xbox不是电子产品的直接子项),而不重复发现的产品在不止一个类别,如I-PAD2。
我可以在PHP的应用程序的帮助下做到这一点,但我想知道是否可以在MySQL中使用纯sql做到这一点?
使用邻接列表模型,您要做的事情相当困难。 正如@Mike建议的那样,使用嵌套集模型会使这更容易。 或者通过您的PHP代码执行它甚至会更容易。
但是,假设您知道可能有多少父子级别(或者您可以假设不会超过X),您可以尝试这样的事情。 如果MySQL支持CTE,这将更容易阅读,但不幸的是,它没有。 在这个例子中,我已经深入了4级 - 你可以深入了解。
SELECT p.Id, p.Title, p.Qty
FROM Products p
JOIN Cats_Products cp on p.id = cp.product_id
WHERE cp.cat_id IN (
SELECT c.id
FROM Cats c
WHERE c.title = 'Electronics'
UNION ALL
SELECT c2.id
FROM Cats c
LEFT JOIN Cats c2 ON c.id = c2.parent
WHERE c.title = 'Electronics'
UNION ALL
SELECT c3.id
FROM Cats c
LEFT JOIN Cats c2 ON c.id = c2.parent
LEFT JOIN Cats c3 ON c2.id = c3.parent
WHERE c.title = 'Electronics'
UNION ALL
SELECT c4.id
FROM Cats c
LEFT JOIN Cats c2 ON c.id = c2.parent
LEFT JOIN Cats c3 ON c2.id = c3.parent
LEFT JOIN Cats c4 ON c3.id = c4.parent
WHERE c.title = 'Electronics'
)
GROUP BY p.Id, p.Title, p.Qty
这是SQL小提琴 。
祝好运。
这是你提问的第一部分。 你能否更详细地解释孩子的部分? 我想这与猫的父母有关。
试试这个:
SELECT distinct(p.title)
FROM cats AS c
JOIN cats_products AS cp
ON cp.cat_id = c.id AND c.title = "Electronics"
JOIN products AS p
ON p.id = cp.product_id;
样本数据:
CREATE TABLE cats
(`id` int, `parent` int, `title` varchar(11), `desc` varchar(9))
;
INSERT INTO cats
(`id`, `parent`, `title`, `desc`)
VALUES
(1, 0, 'top', 'top level'),
(2, 1, 'Electronics', ''),
(3, 2, 'Gaming', ''),
(4, 2, 'Computers', ''),
(5, 4, 'Tablets', ''),
(6, 1, 'Food', ''),
(7, 3, 'Xbox', '')
;
CREATE TABLE products
(`id` int, `title` varchar(13), `qty` int)
;
INSERT INTO products
(`id`, `title`, `qty`)
VALUES
(1, 'ToshibaTV', 5),
(2, 'I-PAD2', 9),
(3, 'Laser Pen', 24),
(4, 'Asus Notebook', 5)
;
CREATE TABLE cats_products
(`id` int, `product_id` int, `cat_id` int)
;
INSERT INTO cats_products
(`id`, `product_id`, `cat_id`)
VALUES
(1, 2, 3),
(2, 2, 5),
(3, 1, 2),
(4, 3, 2),
(5, 4, 4)
;
编辑第二部分 :
SELECT distinct(v.title) FROM products AS v
JOIN (
SELECT Y.product_id FROM cats_products AS Y
JOIN(
SELECT distinct(z.id) FROM cats AS Z
JOIN
(SELECT c.parent
FROM cats AS c
JOIN cats_products AS cp
ON cp.cat_id = c.id
AND c.title = "Electronics") AS X
ON x.parent = z.parent) AS W
ON W.id = Y.cat_id) AS u
ON u.product_id = v.id
;
样本数据
CREATE TABLE cats
(`id` int, `parent` int, `title` varchar(11), `desc` varchar(9))
;
INSERT INTO cats
(`id`, `parent`, `title`, `desc`)
VALUES
(1, 0, 'top', 'top level'),
(2, 1, 'Electronics', ''),
(3, 2, 'Gaming', ''),
(4, 2, 'Computers', ''),
(5, 4, 'Tablets', ''),
(6, 1, 'Food', ''),
(7, 3, 'Xbox', '')
;
CREATE TABLE products
(`id` int, `title` varchar(13), `qty` int)
;
INSERT INTO products
(`id`, `title`, `qty`)
VALUES
(1, 'ToshibaTV', 5),
(2, 'I-PAD2', 9),
(3, 'Laser Pen', 24),
(4, 'Asus Notebook', 5),
(5, 'French Fries', 50)
;
CREATE TABLE cats_products
(`id` int, `product_id` int, `cat_id` int)
;
INSERT INTO cats_products
(`id`, `product_id`, `cat_id`)
VALUES
(1, 2, 3),
(2, 2, 5),
(3, 1, 2),
(4, 3, 2),
(5, 4, 4),
(5, 5, 6)
;
这是我对您的问题的解释:每个类别都有一个父级,您希望选择具有相同父级的所有其他类别。 更具体的所有产品具有相同的父类别。 SQL FIDDLE DEMO
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.