我有两个表,tickets
和categories
。 categories
表格包含3列感兴趣:id
,name
和path
。数据如下所示:
id | Name | Path ------------------ 1 | ABC | 1 2 | DEF | 1.2 3 | GHI | 1.2.3 4 | JKL | 4 5 | MNO | 4.5 6 | PQR | 4.5.6 9 | STU | 4.5.9
请注意,path
列是l-tree。这意味着代表id=2
的类别是id=1
的子类别,而id=3
是id=2
的子类别。
在我的故障单表格中,有一个名为category_id
的列,它引用了我的类别表中的id
列。每张票证最多可分配一个类别(category_id
可能为空)。
我试图计算每个类别的所有门票。
假设我的票证表如下所示:
ticket_id | ticket_title | category_id 1 | A | 1 2 | B | 2 3 | C | 3 4 | D | 5 5 | F | 5 6 | G | 6 7 | H | 9
我想输出:
category_id | count 1 | 3 2 | 2 3 | 1 4 | 4 5 | 4 6 | 1 9 | 1
我发现我可以通过以下查询获取属于给定类别的所有门票:select * from tickets where category_id in (select id from categories where path ~ '*.1.*');
(虽然现在我正在写这个问题我是' m不相信这是正确的。)
我还试图按类别执行逐个计票的问题,我想出了:
SELECT categories.id as cid, COUNT(*) as tickets_count FROM tickets LEFT JOIN categories ON tickets.category_id = categories.id GROUP BY cid;
输出以下内容:
c_id | count 1 | 1 2 | 1 3 | 1 5 | 2 6 | 1 9 | 1
我不太擅长SQL。是否有可能实现我想要的目标?
答案 0 :(得分:1)
你很接近,但你需要一个更通用的-1
:
join
比较中的SELECT c.id as cid, COUNT(*) as tickets_count
FROM categories c LEFT JOIN
tickets t
ON t.category_id || '.' LIKE c.id || '.%'
GROUP BY c.id;
只是因为'.'
与1.100
不匹配。
答案 1 :(得分:1)
试试这个:
WITH tickets_per_path AS (
SELECT
c.path AS path,
count(*) AS count
FROM tickets t INNER JOIN categories c ON (t.category_id = c.id)
GROUP BY c.path)
SELECT
c.id,
sum(tickets_per_path.count) AS count
FROM categories c LEFT JOIN tickets_per_path ON (c.path @> tickets_per_path.path)
GROUP BY c.id
ORDER BY c.id;
产生以下结果:
id| count
1 | 3
2 | 2
3 | 1
4 | 4
5 | 4
6 | 1
9 | 1
大致如下: