考虑以下模式,第3个表是提到的年/月助手表.辅助表非常常见,可以自然地在整个代码中重复使用.我会留给你加载大量的日期数据.但是请注意每个月的结束日期是为那些想要做更少工作的人组合在一起的,同时允许数据库引擎为我们计算闰年.

您可以在该帮助程序表中只有一列.但是这需要在一些函数中使用函数调用结束日期,这意味着更慢.我们喜欢快.

架构

create table workerRecords

( id int auto_increment primary key,

the_date date not null,

staff_no int not null

);

-- truncate workerRecords;

insert workerRecords(the_date,staff_no) values

('2016-06-10',1),

('2016-06-09',1),

('2016-05-09',1),

('2016-04-09',1),

('2016-03-02',2),

('2016-07-02',2);

create table workers

( staff_no int primary key,

full_name varchar(100) not null

);

-- truncate workers;

insert workers(staff_no,full_name) values

(1,'David Higgins'),(2,"Sally O'Riordan");

下面的助手表

create table ymHelper

( -- Year Month helper table. Used for left joins to pick up all dates.

-- PK is programmer's choice.

dtBegin date primary key, -- by definition not null

dtEnd date null

);

-- truncate ymHelper;

insert ymHelper (dtBegin,dtEnd) values

('2015-01-01',null),('2015-02-01',null),('2015-03-01',null),('2015-04-01',null),('2015-05-01',null),('2015-06-01',null),('2015-07-01',null),('2015-08-01',null),('2015-09-01',null),('2015-10-01',null),('2015-11-01',null),('2015-12-01',null),

('2016-01-01',null),('2016-02-01',null),('2016-03-01',null),('2016-04-01',null),('2016-05-01',null),('2016-06-01',null),('2016-07-01',null),('2016-08-01',null),('2016-09-01',null),('2016-10-01',null),('2016-11-01',null),('2016-12-01',null),

('2017-01-01',null),('2017-02-01',null),('2017-03-01',null),('2017-04-01',null),('2017-05-01',null),('2017-06-01',null),('2017-07-01',null),('2017-08-01',null),('2017-09-01',null),('2017-10-01',null),('2017-11-01',null),('2017-12-01',null),

('2018-01-01',null),('2018-02-01',null),('2018-03-01',null),('2018-04-01',null),('2018-05-01',null),('2018-06-01',null),('2018-07-01',null),('2018-08-01',null),('2018-09-01',null),('2018-10-01',null),('2018-11-01',null),('2018-12-01',null),

('2019-01-01',null),('2019-02-01',null),('2019-03-01',null),('2019-04-01',null),('2019-05-01',null),('2019-06-01',null),('2019-07-01',null),('2019-08-01',null),('2019-09-01',null),('2019-10-01',null),('2019-11-01',null),('2019-12-01',null);

-- will leave as an exercise for you to add more years. Good idea to start, 10 in either direction, at least.

update ymHelper set dtEnd=LAST_DAY(dtBegin); -- data patch. Confirmed leap years.

alter table ymHelper modify dtEnd date not null; -- there, ugly patch above worked fine. Can forget it ever happened (until you add rows)

-- show create table ymHelper; -- this confirms that dtEnd is not null

这是一个帮手表.设置一次并忘记它几年

注意:不要忘记运行上面的更新stmt

快速测试您的查询

SELECT DATE_FORMAT(ymH.dtBegin,'%b %Y') as month,

ifnull(COUNT(wr.the_date),0) as total_records,@soloName as full_name

FROM ymHelper ymH

left join workerRecords wr

on wr.the_date between ymH.dtBegin and ymH.dtEnd

and wr.staff_no = 1 and wr.the_date between '2016-04-01' and '2016-07-31'

LEFT JOIN workers w on w.staff_no = wr.staff_no

cross join (select @soloName:=full_name from workers where staff_no=1) xDerived

WHERE ymH.dtBegin between '2016-04-01' and '2016-07-31'

GROUP BY ymH.dtBegin

order by ymH.dtBegin;

+----------+---------------+---------------+

| month | total_records | full_name |

+----------+---------------+---------------+

| Apr 2016 | 1 | David Higgins |

| May 2016 | 1 | David Higgins |

| Jun 2016 | 2 | David Higgins |

| Jul 2016 | 0 | David Higgins |

+----------+---------------+---------------+

它工作正常.第一个mysql表是Helper表.左连接以引入工作记录(允许为空).我们暂停一下这就是你的问题的重点:缺少数据.最后是一个交叉连接的工作表.

交叉连接是初始化作为工作者名称的变量(@soloName).虽然你请求的缺失日期的空状态通过返回0的ifnull()函数被很好地获取,但是对于工人的名字我们没有那么奢侈.这迫使交叉连接.

交叉连接是笛卡尔积.但由于它是一行,我们不会遇到笛卡尔因导致结果集中许多行的正常问题.无论如何,它的工作原理.

但是这里有一个问题:可以看出,在6个地方维护和插入值太难了.因此,请考虑下面的存储过程.

存储过程

drop procedure if exists getOneWorkersRecCount;

DELIMITER $$

create procedure getOneWorkersRecCount

(pStaffNo int, pBeginDt date, pEndDt date)

BEGIN

SELECT DATE_FORMAT(ymH.dtBegin,'%b %Y') as month,ifnull(COUNT(wr.the_date),0) as total_records,@soloName as full_name

FROM ymHelper ymH

left join workerRecords wr

on wr.the_date between ymH.dtBegin and ymH.dtEnd

and wr.staff_no = pStaffNo and wr.the_date between pBeginDt and pEndDt

LEFT JOIN workers w on w.staff_no = wr.staff_no

cross join (select @soloName:=full_name from workers where staff_no=pStaffNo) xDerived

WHERE ymH.dtBegin between pBeginDt and pEndDt

GROUP BY ymH.dtBegin

order by ymH.dtBegin;

END$$

DELIMITER ;

多次测试存储过程

call getOneWorkersRecCount(1,'2016-04-01','2016-06-09');

call getOneWorkersRecCount(1,'2016-04-01','2016-06-10');

call getOneWorkersRecCount(1,'2016-04-01','2016-07-01');

call getOneWorkersRecCount(2,'2016-02-01','2016-11-01');

啊,更容易使用(在PHP,c#,Java,你的名字).选择是你的,存储过程与否.

奖金存储过程

drop procedure if exists getAllWorkersRecCount;

DELIMITER $$

create procedure getAllWorkersRecCount

(pBeginDt date, pEndDt date)

BEGIN

SELECT DATE_FORMAT(ymH.dtBegin,'%b %Y') as month,ifnull(COUNT(wr.the_date),0) as total_records,w.staff_no,w.full_name

FROM ymHelper ymH

cross join workers w

left join workerRecords wr

on wr.the_date between ymH.dtBegin and ymH.dtEnd

and wr.staff_no = w.staff_no and wr.the_date between pBeginDt and pEndDt

-- LEFT JOIN workers w on w.staff_no = wr.staff_no

-- cross join (select @soloName:=full_name from workers ) xDerived

WHERE ymH.dtBegin between pBeginDt and pEndDt

GROUP BY ymH.dtBegin,w.staff_no,w.full_name

order by ymH.dtBegin,w.staff_no;

END$$

DELIMITER ;

快速测试一下

call getAllWorkersRecCount('2016-03-01','2016-08-01');

+----------+---------------+----------+-----------------+

| month | total_records | staff_no | full_name |

+----------+---------------+----------+-----------------+

| Mar 2016 | 0 | 1 | David Higgins |

| Mar 2016 | 1 | 2 | Sally O'Riordan |

| Apr 2016 | 1 | 1 | David Higgins |

| Apr 2016 | 0 | 2 | Sally O'Riordan |

| May 2016 | 1 | 1 | David Higgins |

| May 2016 | 0 | 2 | Sally O'Riordan |

| Jun 2016 | 2 | 1 | David Higgins |

| Jun 2016 | 0 | 2 | Sally O'Riordan |

| Jul 2016 | 0 | 1 | David Higgins |

| Jul 2016 | 1 | 2 | Sally O'Riordan |

| Aug 2016 | 0 | 1 | David Higgins |

| Aug 2016 | 0 | 2 | Sally O'Riordan |

+----------+---------------+----------+-----------------+

外卖

辅助表已经使用了几十年.不要害怕或不好意思使用它们.事实上,试图在没有它们的情况下完成一些专业工作有时几乎是不可能的.

mysql 每个月的月底_即使mysql表中不存在月份,也要选择每个月相关推荐

  1. mysql为什么行数据库_关系数据表中的行称为什么?

    在一个二维表中,水平方向的行称为元组,每一行是一个元组:元组对应表中的一个具体记录. 数据元组也称为记录.一个数据表中的每一个记录均有一个惟一的编号(记录号).一个记录也就是数据表中的一行. 元组(t ...

  2. mysql 索引空间大小_查看数据库表中容量大小,表有多少记录,占多少空间以及索引的大小,以及未使用空间...

    直接在sqlserver查询窗执行就OK了,也是网上看到的,对日常管理数据库工作者来说也蛮有用的,可以及时的清理冗余的数据,缓解数据库服务器的压力. Create Table #TableSpaceI ...

  3. mysql执行计划查看_查看Mysql执行计划

    1.MySQL语法 MySql提供了EXPLAIN语法用来进行查询分析,在SQL语句前加一个"EXPLAIN"即可. 默认情况下Mysql的profiling是关闭的,所以首先必须 ...

  4. MySQL之创建函数,一次性插入表中多行数据

    MySQL之创建函数,一次性插入表中多行数据 一.MySQL之使用存储过程创建函数,一次性插入表中多行数据 一.MySQL之使用存储过程创建函数,一次性插入表中多行数据 #DELIMITER 的使用 ...

  5. panda 透视表 计算比例_数据透视表中有趣的那些事,你知道吗?

    大家好呀~ 想必大家多少都会些数据透视表的常用用法,如果一点都不了解,雷哥还是建议朋友学习一下奥,数据透视表比筛选功能强大很多奥,只要:[选择表中的非空单元格]→[插入]→[数据透视表]→[确定]→[ ...

  6. mysql杠杆加号什么意思_对tb_book表中的数据,按ID序号进行升序排列,查询语句是什么?_学小易找答案...

    [单选题]修改数据库表结构用以下哪一项 ( ) [单选题]对于一个微小物理量,通常采用将其进行放大的方法实现测量,以下哪个不是物理实验方法? [单选题]扭摆实验中,为了测出金属匀质细杆绕质心对称轴的转 ...

  7. mysql join on 索引_连接查询,表关联查询join on,索引,触发器,视图

    一.连接查询 1.统计每一个部门的人数  "部门名,部门的人数" select department,count(eid) from employee group by depar ...

  8. mysql中标记某条数据库_一个关系数据库表中的各条记录可以什么

    一个关系数据库表中的各条记录前后顺序可以任意颠倒,不影响数据库中数据的实际意义.一个关系数据库的表中有多条记录,记录之间的前后顺序并不会对库中的数据关系产生影响,所以行的顺序是无所谓的,可以任意颠倒. ...

  9. mysql 控制id复原_清空mysql表后,自增id复原

    一.清除mysql表中数据 deletefrom表名; truncate table 表名; 不带where参数的delete语句可以删除mysql表中所有内容,使用truncate table也可以 ...

  10. mysql 文章 字段设计_在mysql数据库中,文章表设计有啥好的思路

    Q: 用mysql设计一张文章表,不知道有啥好的思路! 我是这样的,应为考虑附件和图片,所以我的文章表除了有varchar(1000)的文章内容,还设置了个Bolb接收附件和图片. 我用的是mysql ...

最新文章

  1. CodeForces 609B The Best Gift
  2. Alt + sysrq + REISUB doesn't reboot my laptop
  3. 如何迭代pandas dataframe的行
  4. 国家发改委:春运期间推动“健康码”全国一码通行
  5. 2.3 残差网络-深度学习第四课《卷积神经网络》-Stanford吴恩达教授
  6. matlab 二维线图绘制函数 plot用法参数
  7. springboot(2.2.4)配置druid的log4j2日志监控
  8. 有关替换字符的代码问题
  9. python中urllib.parse啥意思_python-urllib.parse模块简述
  10. 网管工具-snmpset使用总结
  11. MCGS_嵌入版7.2软件的下载与安装
  12. (机器人学导论--运动学)(三)DH表达法顺向运动学
  13. excel文件损坏修复绝招_ps文件损坏有修复的软件!超强开挂辅助神器
  14. SAP 未审批的采购订单(PO)提交到OA去审批,最后OA审批结果回写到SAP。
  15. 如何在Android上查看本地空气质量指数
  16. windows电脑打开jnlp文件设置
  17. 中国移动通信互联网短信网关接口协议及相关下载
  18. verilog并行数据转换为串行输出
  19. 〖全域运营实战白宝书 - 高转化文案速成篇⑤〗- 如何撰写内容型文案?
  20. Day001:Excel数据分析

热门文章

  1. [请教] 关于把mscomm控件封装进dll的
  2. 大数据在应急管理中的应用 1
  3. PCB板、电路原理图设计工具 Altium Designer v23.1.1.15 安装教程
  4. 分享73个ASP影音娱乐源码,总有一款适合您
  5. 互联网项目管理流程总结
  6. NFS的at-most-once语义实现操作的幂等性
  7. COJ1976-搬运工小明
  8. springboot化妆品选购平台
  9. python django mysql安装_Python的开发环境安装(MySQL、Django、PyCharm)
  10. 7-1 打印三角形拼图 (15 分)