(MySQL) MPTT / 嵌套集模型上的聚合函数

发布于 2024-10-25 10:21:03 字数 1356 浏览 1 评论 0原文

因此,我使用 MySQL 并将基于嵌套集/修改的前序树遍历模型的类别结构存储在一个名为“nested_category”的表中,该表具有以下字段: category_id名称lftrgt已发布

已发布 为 1 或 0...如果为 1,则该类别将显示在实时网站上。如果它是 0,那么它不会显示在实时网站上,更重要的是,该未发布类别的任何子级也不会显示在实时网站上。

我在编写查询来列出具有 published=1 的所有类别,并忽略属于具有 published=0 的类别的后代的所有类别时遇到问题。

目前我正在使用:

SELECT category_id, lft, rgt FROM nested_category WHERE published = 1

当父项“未发布”时,我真的不知道如何让它忽略“子”类别。

我还尝试将其链接到我的“new_products”表,该表包含以下字段:product_idnamestockprice< /code>, category_id,以便我可以编写一个查询来选择具有 published=1 且属于“已发布”类别的所有产品。我已经做到了这一点:

select @myRight := rgt, @myLeft := lft 
from nested_category where name="ELECTRONICS";

select productId, productName, new_products.category_id, 
price, stock, new_products.published 
from new_products 
inner join ( 
    select category_id, lft, rgt from nested_category 
    where published = 1
) cat 
on new_products.category_id = cat.category_id 
and cat.lft >= @myLeft 
and cat.rgt <= @myRight 
and new_products.published = 1 
order by productName asc

由于上面的查询使用我的第一个查询,它不会返回任何“未发布”类别或产品,但它不会考虑“已发布”类别何时是“未发布”类别的后代类别。 希望这是有道理的!

So I'm using MySQL and storing my category structure based on the Nested Set / Modified Pre-Order Tree Traversal model, in a table name "nested_category" which has fields:
category_id, name, lft, rgt, published

published is either 1 or 0... If it's 1 then the category will show upon the live site. If it's 0 then it won't show on the live site, and more importantly any children of that unpublished category won't show on the live site either.

I'm having problems writing a query to list all the categories that have published=1, and ignore all categories that are descendants of a category which has published=0.

At the moment I'm using:

SELECT category_id, lft, rgt FROM nested_category WHERE published = 1

I really can't work out how to get it to ignore "child" categories when a parent is "unpublished".

I'm also trying to link this to my "new_products" table which has fields: product_id, name, stock, price, category_id, so that I can write a query to select all products that have published=1 and are part of a "published" category. I have got this far:

select @myRight := rgt, @myLeft := lft 
from nested_category where name="ELECTRONICS";

select productId, productName, new_products.category_id, 
price, stock, new_products.published 
from new_products 
inner join ( 
    select category_id, lft, rgt from nested_category 
    where published = 1
) cat 
on new_products.category_id = cat.category_id 
and cat.lft >= @myLeft 
and cat.rgt <= @myRight 
and new_products.published = 1 
order by productName asc

Since the above query uses my first query, it doesn't return any "unpublished" categories or products, but it doesn't take into account when a "published" category is a descendant of an "unpublished" category.
Hope this makes sense!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

黑寡妇 2024-11-01 10:21:04

节点深度略有改善:

SELECT node.name, node.category_id, node.lft, node.rgt, (COUNT(parent.name) - 1) AS depth
FROM nested_category as node
LEFT JOIN (
    SELECT nested_category.category_id, nested_category.lft, nested_category.rgt 
    FROM nested_category, (
        SELECT category_id, lft, rgt 
        FROM nested_category 
        WHERE published = 0
    ) notNodeCat 
    WHERE nested_category.lft >= notNodeCat.lft 
    AND nested_category.rgt <= notNodeCat.rgt ) notNodeCat2
ON notNodeCat2.category_id=node.category_id,
nested_category as parent
LEFT JOIN (
    SELECT nested_category.category_id, nested_category.lft, nested_category.rgt 
    FROM nested_category, (
        SELECT category_id, lft, rgt 
        FROM nested_category 
        WHERE published = 0
    ) notParentCat 
    WHERE nested_category.lft >= notParentCat.lft 
    AND nested_category.rgt <= notParentCat.rgt ) notParentCat2
ON notParentCat2.category_id=parent.category_id            
WHERE notNodeCat2.category_id IS NULL AND notParentCat2.category_id IS NULL AND node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft ASC

Little bit improved with depth of nodes:

SELECT node.name, node.category_id, node.lft, node.rgt, (COUNT(parent.name) - 1) AS depth
FROM nested_category as node
LEFT JOIN (
    SELECT nested_category.category_id, nested_category.lft, nested_category.rgt 
    FROM nested_category, (
        SELECT category_id, lft, rgt 
        FROM nested_category 
        WHERE published = 0
    ) notNodeCat 
    WHERE nested_category.lft >= notNodeCat.lft 
    AND nested_category.rgt <= notNodeCat.rgt ) notNodeCat2
ON notNodeCat2.category_id=node.category_id,
nested_category as parent
LEFT JOIN (
    SELECT nested_category.category_id, nested_category.lft, nested_category.rgt 
    FROM nested_category, (
        SELECT category_id, lft, rgt 
        FROM nested_category 
        WHERE published = 0
    ) notParentCat 
    WHERE nested_category.lft >= notParentCat.lft 
    AND nested_category.rgt <= notParentCat.rgt ) notParentCat2
ON notParentCat2.category_id=parent.category_id            
WHERE notNodeCat2.category_id IS NULL AND notParentCat2.category_id IS NULL AND node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft ASC
你好,陌生人 2024-11-01 10:21:04

好吧,在玩了很多之后,我已经拼凑了一些有效的东西...

SELECT nested_category.name, nested_category.category_id, nested_category.lft, nested_category.rgt 
FROM nested_category 
LEFT JOIN (
    SELECT nested_category.category_id, nested_category.lft, nested_category.rgt 
    FROM nested_category, (
        SELECT category_id, lft, rgt 
        FROM nested_category 
        WHERE published = 0
    ) notCat 
    WHERE nested_category.lft >= notCat.lft 
    AND nested_category.rgt <= notCat.rgt ) notCat2
ON notCat2.category_id=nested_category.category_id 
WHERE notCat2.category_id IS NULL
ORDER BY nested_category.lft ASC

它显示了所有具有 published=1 的nested_category 项目,这些项目没有被父级 阻止published=0

我确实需要帮助的一件事是使用更多的左连接重写它,因为我听说它们更有效!

Okay so after playing around a LOT, I've hacked together something that is working...

SELECT nested_category.name, nested_category.category_id, nested_category.lft, nested_category.rgt 
FROM nested_category 
LEFT JOIN (
    SELECT nested_category.category_id, nested_category.lft, nested_category.rgt 
    FROM nested_category, (
        SELECT category_id, lft, rgt 
        FROM nested_category 
        WHERE published = 0
    ) notCat 
    WHERE nested_category.lft >= notCat.lft 
    AND nested_category.rgt <= notCat.rgt ) notCat2
ON notCat2.category_id=nested_category.category_id 
WHERE notCat2.category_id IS NULL
ORDER BY nested_category.lft ASC

It displays all nested_category items that have a published=1 that are not blocked off by a parent being published=0

One thing I do need help with is re-writing it using more left joins, as I hear they're more efficient!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文