我想从以下数据库表'article'中获取一些数据。
我想获取category_id为4的文章信息。但结果应该包含其父类别的所有记录。
例如:
'article1'的父级为'Sub Category1',其父级为'Main Category'。所以结果应该是表格中的1,2,4行。
是否可以为此编写一个SQL查询?什么是可以根据上述条件获取数据的查询?
请指导我.. !!
感谢..
答案 0 :(得分:4)
请参阅此文:Managing Hierarchical Data in MySQL。
实际上,他们的目的是模型来获得没有递归的分层数据。 因为他们使用lft(左)和rgt(右)这个额外的列来存储表的结构信息。 lft和rgt设置如下
Root lft是1.然后它的第一个子lft是下一个数字然后它的子进入下一个数字,直到没有孩子然后该节点(叶节点)rgt将是它的lft +1。 我们将兄弟姐妹lft设置为rgt +1,并遵循相同的规则。
如果所有孩子的编号都已完成,则会将父母rgt设为上一个孩子的rgt +1。
我没有整齐地解释它,但在与图像的链接上它更容易理解。
在此之后,您可以使用以下查询轻松探索嵌套结构
按顺序获取所有父母的身份:
SELECT parent.category_id
FROM article AS node,
article AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
AND node.category_id = $category_id
ORDER BY parent.lft;
删除任何行:
LOCK TABLE article WRITE;
SELECT @myLeft := lft, @myRight := rgt, @myWidth := rgt - lft + 1
FROM article WHERE category_id = 'row_id';
DELETE FROM article WHERE lft BETWEEN @myLeft AND @myRight;
UPDATE article SET rgt = rgt - @myWidth WHERE rgt > @myRight;
UPDATE article SET lft = lft - @myWidth WHERE lft > @myRight;
UNLOCK TABLES;
用于插入任何行:
LOCK TABLE article WRITE;
SELECT @myLeft := lft FROM article WHERE category_id = 'parent_id';
UPDATE article SET rgt = rgt + 2 WHERE rgt > @myLeft;
UPDATE article SET lft = lft + 2 WHERE lft > @myLeft;
INSERT INTO article(title, lft, rgt) VALUES('title', @myLeft + 1, @myLeft + 2);
UNLOCK TABLES;
这有点复杂,但在创建存储过程后,使用起来并不困难。
答案 1 :(得分:2)
在MS SQL 2005/2008中:
with cte(category_id, parent_id, title)
as
(
select category_id, parent_id, title
from Category
where category_id = 4
union all
select cat.category_id, cat.parent_id, cat.title
from Category cat
join cte on
cat.category_id = cte.parent_id
)
select *
from cte
答案 2 :(得分:1)
这在SQL中称为RECURSIVE查询。 Oracle和Postgresql使用与Alex Aza的答案不同的语法,在MySQL中,我认为你不能在一个查询中完成它。
WITH RECURSIVE t(category_id, parent_id, title) AS
(SELECT category_id, parent_id, title
from Category
where category_id = 4)
UNION ALL
SELECT c.category_id, c.parent_id, c.title
FROM Category c, t WHERE t.parent_id=c.category_id /* ends when parent_id==-1 */
)
SELECT * FROM t;
RECURSIVE
是必需的。
答案 3 :(得分:0)
如果您使用的是sqlserver 2008,请尝试使用hierarchyid MSDN