Oracle:过去12个月创建的Count实体

时间:2015-01-05 09:25:43

标签: sql oracle oracle10g

我正在寻找一种方法来获取过去12个月创建的实体数量。我试了一下,但我有两个问题:

  • 我只有当年的12个月
  • 如果在一个月内没有创建实体,我的查询将返回null。

我的sql:

SELECT COUNT(*) 
FROM users 
WHERE extract(year FROM signin_date) = ? 
GROUP BY extract(month FROM signin_date)

在sql中有什么方法可以得到这样的东西吗?

| COUNT |
| 0     |      (january 2014)
| 3     |      (february 2014)
| 0     |      (march 2014)
...

我还发现:SQL select multiple counts in the last 12 months including missing months 但我真的不明白如何适应我的问题。

2 个答案:

答案 0 :(得分:2)

我假设您希望在表中没有行的月份中包含零计数。为此,您首先需要创建可能月份的列表,然后使用外部联接。

with month_numbers as (
  select level as month
  from dual
  connect by level <= 12
), this_year_users as (
  select id, extract(month FROM u.signin_date) as signin_month
  from users
  where extract(year FROM signin_date) = ? 
)
select mn.month, count(u.id) 
from month_numbers mn
  left join this_year_users u on u.signin_month = mn.month
group by mn.month;

第一个公用表表达式是生成连续数字列表的技巧,您可以在以后加入。

第二个公用表表达式只选择本月的所有用户。然后最终选择在“所有月份”和过滤的用户表之间进行外部联接,计算每个月的用户数。该查询假定id表中有一个名为users的非可空列(例如主键)。


如果您想要“过去12个月”,您需要一个不同的可能“日期”列表,其中不仅包括月份编号,还包括处理上一年间隔的年份:

with month_numbers as (
  select to_char(add_months(trunc(current_date), -level), 'yyyy-mm') as month
  from dual
  connect by level <= 12
)
select mn.month, count(u.signin_date) 
from month_numbers mn
  left join users u on to_char(u.signin_date, 'yyyy-mm') = mn.month
group by mn.month
order by mn.month;

这不包括“当前月份”,如果您愿意,只需将-level替换为-(level - 1) CTE中的month_numbers

SQLFiddle示例:http://sqlfiddle.com/#!4/e02ac/2

答案 1 :(得分:0)

试试这段代码。

SELECT COUNT(*) 
FROM users 
WHERE signin_date > add_months(CURRENT_DATE, -12)
GROUP BY extract(month FROM signin_date)