我有一个SQLite表,其中有一列包含每行可能属于的类别。每行都有一个唯一的ID,但可能属于零个,一个或多个类别,例如:
|------------+-------|
| categories | total |
|------------+-------|
| a | 2 |
| b | 2 |
| c | 2 |
| none | 1 |
|------------+-------|
我希望获得每个类别中有多少项目的计数。换句话说,输出如下:
case
我尝试使用这样的select case
when cats like "%a%" then 'a'
when cats like "%b%" then 'b'
when cats like "%c%" then 'c'
else 'none'
end as categories,
count(*)
from test
group by categories
语句:
|------------+-------|
| categories | total |
|------------+-------|
| a | 2 |
| b | 1 |
| none | 1 |
|------------+-------|
但问题是这只计算每行一次,因此无法处理多个类别。然后,您将获得此输出:
union
一种可能性是使用与您有类别一样多的select case
when cats like "%a%" then 'a'
end as categories, count(*)
from test
group by categories
union
select case
when cats like "%b%" then 'b'
end as categories, count(*)
from test
group by categories
union
...
语句:
{{1}}
但这看起来真的很难看,与DRY相反。
有更好的方法吗?
答案 0 :(得分:2)
修复您的数据结构!您应该有一个表格,每个name
和每category
一行:
create table nameCategories (
name varchar(255),
category varchar(255)
);
然后您的查询会很简单:
select category, count(*)
from namecategories
group by category;
为什么您的数据结构不好?以下是一些原因:
考虑到这一点,这里有一种蛮力方法可以做你想做的事情:
with categories as (
select 'a' as category union all
select 'b' union all
. . .
)
select c.category, count(t.category)
from categories c left join
test t
on ' ' || t.categories || ' ' like '% ' || c.category || ' %'
group by c.category;
如果您已有一个有效类别表,则不需要CTE。