繁体   English   中英

用于检索邻接列表模型中某些类别下的所有产品的SQL查询

[英]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)
;

SQL FIDDLE DEMO

编辑第二部分

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM