一、背景描述
- 数据库表描述
现有两张表:
-
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信息。两者之间的关系显而易见。
-
任务描述
这里,我们需要做一个统计信息,统计一天之内的入库信息,比如一天之内入库的所有文件,doc文件总数,pptx文件总数等等。要形成类似如下的统计表信息:日期 文件总数 doc文件总数 pptx文件总数 2017-03-01 2 1 1 2017-03-02 2 1 1 2017-03-03 2 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文件数?
-
解决方案
-
左连接--形成新的中间表
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 whenselect 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
网友评论