如何在SQLite3中“分组”行和列?

时间:2015-02-20 10:37:23

标签: sql sqlite

SQLite数据库表table1

user       command    date       location
---------- ---------- ---------- ----------
user1      cmd1       2015-01-01 xxxdeyyy
user2      cmd1       2015-01-01 zzzfrxxx
user3      cmd1       2015-01-01 yyyukzzz
user1      cmd1       2015-01-01 xxxdezzz
...

预期输出

where command='cmd1'的输出:

month    users_de users_fr users_es
-------- -------- -------- --------
01       1        0        5
02       2        0        0
03       0        2        1
04       5        0        15
05       1        0        4
06       11       1        2
07       9        0        3
08       1        0        5
09       0        0        5
10       0        0        0
11       1        0        0
12       1        4        5

按月分组(来自列date),并按位置中的子字符串(来自列location)进行分组。

实际输出

我可以实现这个目标(每个地点):

month    users_de
-------- --------
01       1       
02       2       
03       0       
...      
12       1       

使用此查询:

select strftime('%m',date) as month, count(distinct user) as users_de 
from table1 
where command='cmd1' and location like '%de%'
group by strftime('%m',date);

然后我为其他位置(where ... and location='fr')重复此查询:

month    users_fr
-------- --------
01       0       
02       0       
03       2       
...
12       4    

和(where ... and location='es');

month    users_es
-------- --------
01       5
02       0
03       1
...
12       5

有没有办法让一个表中的所有users_xx列(作为SQLite的输出,而不是通过任何外部(下游)处理)?

我是否以错误的方式考虑这个问题(在顶部select中分组而不是子查询)?

3 个答案:

答案 0 :(得分:1)

您可以使用case语句匹配每个位置,然后匹配计数用户。

    select strftime('%m',date) as month, 
           CASE WHEN location='de' THEN count(distinct user) END users-de,
           CASE WHEN location='fr' THEN count(distinct user) END users-fr,
           CASE WHEN location='es' THEN count(distinct user) END users-es,  
    from table1 
    where command='cmd1' 
    group by strftime('%m',date),location;

答案 1 :(得分:0)

我认为你想要条件聚合:

select strftime('%m',date) as month, 
       count(distinct CASE WHEN location like '%de%' THEN user END) as users_de,
       count(distinct CASE WHEN location like '%fr%' THEN user END) as users__fr,
       count(distinct CASE WHEN location like '%es%' THEN user END) as users_es
from table1 
where command = 'cmd1' 
group by strftime('%m',date);

两个注释:

    在这种情况下,
  • like可能不安全。您在字符串中嵌入了国家/地区代码,但字符“de”,“es”或“fr”可能出现在字符串的其他位置。关于更好的逻辑,你的问题并不明确。
  • 您应该在日期字符串中包含年份,但您的问题仅包含月份。

答案 2 :(得分:-2)

使用这样的查询:

SELECT strftime('%m',date) AS month,
       location,
       count(distinct user) AS users-de,
       count(distinct user) AS users-fr,
       count(distinct user) AS users-es
  FROM table1 
 WHERE command='cmd1' GROUP BY strftime('%m', date), location;