Oracle按日期统计表信息

一、背景描述


  1. 数据库表描述
    现有两张表:
  • table1->t_zip

    ZIP_ID ZIP_NAME FILE_NUM ZIP_TIME
    1 1.zip 2 2017-03-01 12:00:01
    2 2.zip 2 2017-03-02 12:00:02
    3 3.zip 2 2017-03-03 12:00:03
  • table2->t_file

    ZIP_ID FILE_NAME FILE_ATTR
    1 1.doc 1
    2 2.txt 2
    3 3.pptx 3
    1 a.doc 1
    2 b.txt 2
    3 c.pptx 3
  • 表关系描述
    t_zip表记录的是有关一个ZIP文件的描述,包含zip文件的名字,内含文件数和入库时间,当然,这里做了简化。
    t_file表记录的是有关一个ZIP包内一个文件的信息描述,包含文件名字和文件属性。
    两张表之间通过ZIP_ID来建立联系,t_zip对t_file是一对多的关系,即一条zip信息对应多条file信息。两者之间的关系显而易见。

  1. 任务描述
    这里,我们需要做一个统计信息,统计一天之内的入库信息,比如一天之内入库的所有文件,doc文件总数,pptx文件总数等等。要形成类似如下的统计表信息:

    日期 文件总数 doc文件总数 pptx文件总数
    2017-03-01 2 1 1
    2017-03-02 2 1 1
    2017-03-03 2 1 1

二、技术思路及其实现


  1. 主要问题
    现在主要问题是需要统计的信息在t_file表中,而信息分类所需要的日期信息则在t_zip表中,并且t_zip对t_file是一对多的关系。
    单单统计某一天的信息是比较容易的,比如统计2017-03-01这一天的文档总数:

    #这里先将t_zip表中所有属于2017-03-01这天入库的记录的zip_id取出形成新的id表,
    #然后查询t_file表中zip_id属于刚形成的id表中的所有记录的个数
    select count(*) from t_file where zip_id in \
    (select zip_id from t_zip where to_char(zip_time,'yyyy-mm-dd')='2017-03-01')
    

    但是如何自动按照日期分类,而不是手动输入日期,而且可以按照某一列的不同属性来统计信息呢?比如,上面的sql查询语句如何统计03-01这天入库的doc文件数?

  2. 解决方案

  • 左连接--形成新的中间表
    LEFT JOIN是以左表的记录为基础的,示例中t_file可以看成左表,t_zip可以看成右表,它的结果集是t_file表中的全部数据,再加上t_file表和t_zip表匹配后的数据。换句话说,左(t_file)的记录将会全部表示出来,而右表(t_zip)只会显示符合搜索条件的记录。t_zip表记录不足的地方均为NULL。
    两表按照zip_id来进行连接,形成新的表集合,类似如下的表:

    FILE_ATTR FILE_TIME
    1 2017-03-01
    2 2017-03-01

    对应的SQL语句为:

    select f.file_attr file_attr,z.zip_time file_time \
    from t_file f left join t_zip z on f.zip_id=z.zip_id
    
  • 在中间表的基础上查询

    select count(*) 文件总数 from 
    (select select f.file_attr file_attr,z.zip_time file_time \
    from t_file f left join t_zip z on f.zip_id=z.zip_id) a 
    group by file_time
    
  • 同一字段按照不同属性统计
    使用case when

    select count(*) 文件总数,count(case when file_attr='1' then 1 end) doc文件总数, \
    count(case when file_attr='2' then 1 end) txt文件总数 from 、
    (select f.file_attr z.zip_time file_time from t_file f \
     left join t_zip on f.zip_id=z.zip_id) a 
    group by file_time
    

你可能感兴趣的:(Oracle按日期统计表信息)