5

我有两个表:类别和项目。我使用嵌套集结构存储了类别。类别有项目。项目只能添加到根类别的叶节点。

例如:类别

Vehicles
    Bikes
        Bajaj
    Automobiles
Art & Antiques
    Amateur Art

在这种情况下,可以将项目添加到 Bajaj、汽车和业余艺术类别。

假设 Bajaj 中有 2 个项目,汽车中有 5 个项目,业余艺术中有 2 个项目

对于根级别类别,我想显示如下:

- Vehicles (7 items)
- Art & Antiques (2 items)

我怎样才能做到这一点 ?

这是用于处理一些示例数据的 sql 转储

--
-- Table structure for table `categories`
--

CREATE TABLE IF NOT EXISTS `categories` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `parent_id` int(11) DEFAULT NULL,
 `title` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
 `lft` int(11) NOT NULL,
 `lvl` int(11) NOT NULL,
 `rgt` int(11) NOT NULL,
 `root` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
   KEY `IDX_3AF34668727ACA70` (`parent_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=28 ;

--
 -- Dumping data for table `categories`
--

INSERT INTO `categories` (`id`, `parent_id`, `title`, `lft`, `lvl`, `rgt`, `root`)  VALUES
(22, NULL, 'Vehicles', 1, 0, 8, 22),
(23, 22, 'Bikes', 2, 1, 5, 22),
(24, 23, 'Bajaj', 3, 2, 4, 22),
(25, 22, 'Automobiles', 6, 1, 7, 22),
(26, NULL, 'Art & Antiques', 1, 0, 4, 26),
(27, 26, 'Amateur Art', 2, 1, 3, 26);

-- --------------------------------------------------------

--
-- Table structure for table `items`
--

CREATE TABLE IF NOT EXISTS `items` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `category_id` int(11) NOT NULL,
 `title` varchar(100) NOT NULL,
 PRIMARY KEY (`id`),
 KEY `FK_403EA91BA33E2D84` (`category_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

--
-- Dumping data for table `items`
--

INSERT INTO `items` (`id`, `category_id`, `title`) VALUES
(1, 24, 'Pulsor 150 cc'),
(2, 24, 'Discover 125 cc'),
(3, 27, 'Art of dream'),
(4, 25, 'Toyota Car');

--
-- Constraints for dumped tables
--

--
-- Constraints for table `categories`
--
ALTER TABLE `categories`
 ADD CONSTRAINT `FK_3AF34668727ACA70` FOREIGN KEY (`parent_id`) REFERENCES `categories` (`id`) ON DELETE SET NULL;

--
-- Constraints for table `items`
--
ALTER TABLE `items`
 ADD CONSTRAINT `FK_403EA91BA33E2D84` FOREIGN KEY (`category_id`) REFERENCES  `categories` (`id`) ON DELETE CASCADE;

根节点在 parent_id 字段中为 NULL

更新:

我能够使用此查询获取根:

SELECT c.id,c.title,cte.co FROM categories c
JOIN 
(SELECT 
  c0_.id,c0_.root,COUNT(i.id) co
  FROM 
  categories c0_ 
  JOIN items i ON c0_.id=i.category_id
  WHERE c0_.rgt = 1 + c0_.lft
  GROUP BY c0_.id
) cte
ON cte.root=c.id
WHERE c.parent_id is null

上述查询适用于根级别类别。现在,当用户单击根级别类别时,我也想做同样的事情。

例如,当有人点击车辆时,我应该得到:

 Bikes (2)
 Automobiles (5)

为此,我尝试了:

 SELECT c.id,c.title,cte.co FROM categories c
 JOIN 
 (SELECT 
   c0_.id,c0_.root,COUNT(i.id) co
  FROM 
  categories c0_ 
  JOIN items i ON c0_.id=i.category_id
  WHERE 
  c0_.rgt = 1 + c0_.lft
  GROUP BY c0_.id
 ) cte
 ON cte.root=c.id
 WHERE c.parent_id=1

这返回了空结果集。这个查询有什么问题?

4

3 回答 3

2
SELECT parent.title,
( SELECT count(i.id) count FROM items i 
 WHERE category_id IN 
 (
 SELECT child.id FROM categories child WHERE child.lft>=parent.lft AND   
  child.rgt<=parent.rgt AND child.root=parent.root
 )
)
FROM categories parent 
WHERE parent.parent_id=@parent_id;

如果这不起作用,请通知我

于 2013-03-18T06:26:16.193 回答
1

像这样的东西怎么样:

SELECT COUNT(items.id), 
    (SELECT lookup.title 
     FROM categories lookup 
     WHERE lookup.id = categories.root) 
FROM items, categories 
WHERE categories.id = items.category_id 
GROUP BY categories.root;

基于上面脚本的输入给了我:

3 | Vehicles
1 | Art & Antiques

选择特定的根添加

AND categories.root = @id

其中@id 是您要查找的根ID。

或者,如果您想通过根名称进行选择,请执行以下操作(可怕):

SELECT title, total 
    FROM
    (SELECT COUNT(items.id) total, 
            (SELECT lookup.title 
         FROM categories lookup 
         WHERE lookup.id = categories.root) title 
    FROM items, categories 
    WHERE categories.id = items.category_id 
    GROUP BY categories.root;
    ) AS some_table
WHERE some_table.title = @root_name

其中@root_name 是您的根节点的名称(当然在引号中)

于 2013-03-17T04:52:51.050 回答
0

像这样的东西应该工作。

 select c1.title, count(*) itemcount
 from categories c1 join categories c2
 on c2.parent_id = c1.id
 join items on items.category_id = c2.id
 group by c1.title
于 2013-03-17T03:05:40.173 回答