SQL 查询每个月统计的数据。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL 查询每个月统计的数据。相关的知识,希望对你有一定的参考价值。

例如:
月份 count
2012-01 12
2012-02 0
2012-03 13
2013-04 16
2013-05 0

。。。。。。
2013-12 12
如果其中哪个没数据就默认为0.
这个SQL 应该怎么写。 在线等
在数据库月份表里面。 没有2月份,和5月份,这2个月的值。
不好意思 年份弄错了、。 都是查询2012。1月到12月的数据

select 月份,sum(isnull(count,0)) from A group by 月份
你是不是整个月没数据的就自动要补一条记录为0的
我想了一下,简单的这样写,都不可能出现补零的数据,毕竟这个月份的数据并没有出现在表中。
看实际情况,必要时候使用union
既然知道只有两个月的,那就补上
select * from
(
select 月份,sum(isnull(count,0)) from A group by 月份
union all
select '2012-02',0
union all
select '2013-05',0
) a
order by 月份
不过话说你是不是年份弄错了,从2012直接跳到2013?

我这个方法还搞不定吗?
参考技术A 先用一个表变量,然后连表查的
DECLARE @M Table(MData char(2) null)
INSERT INTO @M(MData)VALUES('1')
INSERT INTO @M(MData)VALUES('2')
INSERT INTO @M(MData)VALUES('3')
INSERT INTO @M(MData)VALUES('4')
INSERT INTO @M(MData)VALUES('5')
INSERT INTO @M(MData)VALUES('6')
INSERT INTO @M(MData)VALUES('7')
INSERT INTO @M(MData)VALUES('8')
INSERT INTO @M(MData)VALUES('9')
INSERT INTO @M(MData)VALUES('10')
INSERT INTO @M(MData)VALUES('11')
INSERT INTO @M(MData)VALUES('12')
select a.MData,isnull(b.count,0) from @M as a left join (select datepart(month, 月份)
as date,count(ID) as count
from 表名 group by datepart(month, 月份)) as b on a.MData=b.date追问

有点思路。 但是在我们这边行不通。
不能建表。直接硬写SQL

追答

不能创建表变量?你那是sql的版本2005之前的?

DECLARE @M Table(MData char(2) null)
INSERT INTO @M(MData)VALUES('1')
INSERT INTO @M(MData)VALUES('2')
INSERT INTO @M(MData)VALUES('3')
INSERT INTO @M(MData)VALUES('4')
INSERT INTO @M(MData)VALUES('5')
INSERT INTO @M(MData)VALUES('6')
INSERT INTO @M(MData)VALUES('7')
INSERT INTO @M(MData)VALUES('8')
INSERT INTO @M(MData)VALUES('9')
INSERT INTO @M(MData)VALUES('10')
INSERT INTO @M(MData)VALUES('11')
INSERT INTO @M(MData)VALUES('12')
select * from @M
这样有语法错误吗?要不你试试创建临时表

追问

我们用sqllite数据库。 和PC端连接的。 不是我们后台建表就建表的。 要看PC端

追答

哦,没用过sqllite,等高手来回答吧

本回答被提问者采纳
参考技术B SQL Server 环境下, 使用:

SELECT
DATEADD(mm, number, '2012-01-01')
FROM
master..spt_values
WHERE
type='P'
AND number between 0 and 24

通过上面这个查询, 产生一个连续的 24个月的日期

然后用这个子查询 LEFT JOIN 你的表

然后用 ISNULL 函数, 如果是 NULL 就 为 0
参考技术C select isnull (count,'0') from table
你的要求,只要在你需要查的那列前加isnull(列,'0')就是当为空时为0,那个0可以随意的
还不清楚? select 月份,innull(count(*),'0') from table group by 月份来自:求助得到的回答
参考技术C select 月份,sum(isnull(count,0)) from A group by 月份

sql优化:数据量过大查询优化

1.场景:有大数据的数据需要放到首页统计,一般就是聚合、分组之类的,按照年月日进行查询和统计。如果数据量比较少,几十万数据 没什么问题。但是随着数据量的增多,查询速度越来越慢。这个时候就需要去优化了~

   刚开始自己的想法是这样的:使用多线程的方式,因为查询每天的数据量很少,那么是不是可以使用多线程的方式,每个线程查询一天的,查询一个月30天,就用30个线程,这样速度会不会快些?

于是,用多线程的方式实现了下。代码如下:

 

    private ExecutorService executorService = new ThreadPoolExecutor(30,30,1, TimeUnit.MILLISECONDS,new LinkedBlockingDeque<>());
    public List<Map> getCiServiceBadEvaNumStatistic(SAASIndexQuery saasIndexQuery) throws InvocationTargetException, IllegalAccessException {
        String startDate = saasIndexQuery.getStartDate();
        String endDate = saasIndexQuery.getEndDate();
        int days = DateUtil.getDatebetweenOfDayNum(DateUtil.parseDate(startDate,DateUtil.dateFormatPattern),DateUtil.parseDate(endDate,DateUtil.dateFormatPattern));

        CompletionService<List<CiOrderStatisticSection>> completionService = new ExecutorCompletionService<List<CiOrderStatisticSection>>(executorService);

        List<CiOrderStatisticSection> allList = new ArrayList<>();

        long start = System.currentTimeMillis();
        logger.info("测试异步时间start:" + System.currentTimeMillis());
        //CountDownLatch countDownLatch = new CountDownLatch(days);
        SAASIndexQuery everyDaySaas = new SAASIndexQuery();
        BeanUtils.copyProperties(everyDaySaas,saasIndexQuery);
        for(int i = 0;i<days;i++){
            everyDaySaas.setStartDate(DateUtil.afterNDay(saasIndexQuery.getStartDate(),i,DateUtil.dateFormatPattern));
            everyDaySaas.setEndDate(DateUtil.afterNDay(everyDaySaas.getStartDate(),1,DateUtil.dateFormatPattern));
            //countDownLatch.countDown();
            int finalI = i;
            completionService.submit(new Callable<List<CiOrderStatisticSection>>() {
                @Override
                public List<CiOrderStatisticSection> call() throws Exception {
                    //allList.addAll(biSaasCiDeviceDayExMapper.getCiServiceNegativeRate(saasIndexQuery));
                    //countDownLatch.countDown();
                    System.out.println("====="+ finalI +"=====");
                    return biSaasCiDeviceDayExMapper.getCiServiceNegativeRate(saasIndexQuery);
                }
            });
        }
        System.out.println("==============" + (System.currentTimeMillis()-start) + "毫秒");
        long t = System.currentTimeMillis();
        for (int i = 0;i<days;i++){
            System.out.println("for循环耗时==============+"+i + (System.currentTimeMillis()-t) + "毫秒");

            try {
                Future<List<CiOrderStatisticSection>> future = completionService.take();
                List<CiOrderStatisticSection>  ciList = future.get();
                allList.addAll(ciList);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        long end = System.currentTimeMillis();
        logger.info("测试异步时间end:" + (end-start) + "毫秒");
        System.out.println("测试异步时间end:" + (end-start) + "毫秒");

}

测试后发现不对,使用多线程的take方式 每次都会有阻塞,这个阻塞一直没明白是哪里阻塞了? 是线程池、LinkedBlockingDeque 还是for循环 take时候 阻塞了 一直没明白,观察的结果就是每次for循环都要差不多200多毫秒,30个循环要6s多。。。。额,算了 ,还没有原来快呢

 

 

2.昨天换了种思路:直接从数据库查询时候做好控制。每次查询先根据月份和年份,查询出来id的最大值和最小值,之后sql里面查询时候加上id在这个最大值和最小是区间内。大概思路是这样:嗯,结果竟然可以。

 

以上是关于SQL 查询每个月统计的数据。的主要内容,如果未能解决你的问题,请参考以下文章

sql截止上月查询语句,按月统计

sql怎么统计今年每个月的数据条数

SQL按月统计,按日分组

sql 统计查询(按月统计)

SQL语句怎么按照月统计数量

mysql 查询一年的数据 要按每个月20号统计 如何做 一条语句