Mysql-使用多个联接表查找缺少的日期
我需要一些帮助来编写mysql查询。我需要查找给定日期范围内特定业务id/项目id的所有遗漏报告 基本上,对于给定的业务id,我需要知道项目的名称以及报告缺失或未标记为完成的所有日期 我正在使用日历表技巧(如所述和)查找缺少的报告日期,但在加入项目表以查找缺少报告的关联项目/业务时遇到问题 我基本上需要一个结果集,它将为我提供类似以下内容的数据:Mysql-使用多个联接表查找缺少的日期,mysql,Mysql,我需要一些帮助来编写mysql查询。我需要查找给定日期范围内特定业务id/项目id的所有遗漏报告 基本上,对于给定的业务id,我需要知道项目的名称以及报告缺失或未标记为完成的所有日期 我正在使用日历表技巧(如所述和)查找缺少的报告日期,但在加入项目表以查找缺少报告的关联项目/业务时遇到问题 我基本上需要一个结果集,它将为我提供类似以下内容的数据: +------------+-----------+--------------+ | project_id | name | missin
+------------+-----------+--------------+
| project_id | name | missing_date |
+------------+-----------+--------------+
| 1 | Project 1 | 2014-01-01 |
| 1 | Project 1 | 2014-01-03 |
| 1 | Project 1 | 2014-01-04 |
| 1 | Project 1 | 2014-01-07 |
| 1 | Project 1 | 2014-01-09 |
| 2 | Project 2 | 2014-01-02 |
| 2 | Project 2 | 2014-01-03 |
| 2 | Project 2 | 2014-01-04 |
+------------+-----------+--------------+
这是我的模式:
projects table:
+----------------+------------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+------------------+------+-----+-------------------+----------------+
| project_id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| business_id | int(10) unsigned | NO | MUL | NULL | |
| name | tinytext | YES | | NULL | |
+----------------+------------------+------+-----+-------------------+----------------+
reports table:
+---------------------+------------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+------------------+------+-----+-------------------+----------------+
| report_id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| project_id | int(10) unsigned | NO | MUL | NULL | |
| report_date | date | NO | MUL | NULL | |
| completed | bit(1) | NO | | b'0' | |
+---------------------+------------------+------+-----+-------------------+----------------+
calendar table:
+--------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| dt | date | NO | PRI | NULL | |
| month_name | varchar(9) | YES | | NULL | |
| day_name | varchar(9) | YES | | NULL | |
| y | smallint(6) | YES | | NULL | |
| q | tinyint(4) | YES | | NULL | |
| m | tinyint(4) | YES | | NULL | |
| d | tinyint(4) | YES | | NULL | |
| dw | tinyint(4) | YES | | NULL | |
| w | tinyint(4) | YES | | NULL | |
| is_weekday | bit(1) | YES | | NULL | |
| is_holiday | bit(1) | YES | | NULL | |
| holiday_desc | varchar(32) | YES | | NULL | |
+--------------+-------------+------+-----+---------+-------+
下面的查询用于返回未完成报告的列表,但我仍然需要用完全没有报告记录的日期来填补空白
select
p.project_id,
p.name,
c.dt as missing_date,
r.completed
from reports r
join projects p on (r.project_id = p.project_id)
right join calendar c on (c.dt = r.report_date)
where c.dt >= '2014-02-01'
and c.dt <= '2014-02-10'
-- and r.report_date is null /** THE RESULT SET IS EMPTY IF I UNCOMMENT THIS **/
and r.completed = false
and c.is_holiday = false
and c.is_weekday = true
and p.business_id = 1001
order by p.project_id, r.report_date, c.dt;
选择
p、 项目编号:,
p、 名字,
c、 dt作为缺失的_日期,
r、 完成
来自报告r
加入项目p on(r.project\u id=p.project\u id)
右键连接日历c on(c.dt=r.report\u日期)
其中c.dt>=“2014-02-01”
c.dt我阅读了您提供的链接,这种存储日期的方法非常好。
您在查询中使用的任何方式:
right join calendar c on (c.dt = r.report_date)
但我在你的报告表中没有看到任何报告日期。
我建议您检查问题是否是因为它,因为除此之外,您的查询似乎工作正常。好的,我终于让它工作了。这是一个相当复杂的查询,需要在projects表上进行内部连接,但我不知道更好的方法-我是一个Java人,现在太依赖hibernate来构建查询:)。如果有人有更有效的解决方案,我洗耳恭听
最终查询:
select
p.project_id,
p.name,
c.dt as missing_date,
r.report_date,
r.completed
from calendar c
inner join (
select
p1.project_id,
p1.name
from projects p1
where p1.project_id = 1005
-- where p1.business_id = 1001 /** OR USE THE BUSINESS ID **/
) p on c.dt between '2014-02-01' and '2014-02-28'
left join reports r on r.report_date = c.dt
and r.project_id = p.project_id
and r.completed = false
where (r.report_date is null or r.completed = false)
and c.is_holiday = false
and c.is_weekday = true
order by p.project_id, c.dt;
生成正确的结果:
+------------+--------------+--------------+-------------+-----------+
| project_id | name | missing_date | report_date | completed |
+------------+--------------+--------------+-------------+-----------+
| 1005 | Project 1005 | 2014-02-03 | 2014-02-03 | 0 |
| 1005 | Project 1005 | 2014-02-04 | 2014-02-04 | 0 |
| 1005 | Project 1005 | 2014-02-05 | NULL | NULL |
| 1005 | Project 1005 | 2014-02-06 | 2014-02-06 | 0 |
| 1005 | Project 1005 | 2014-02-07 | NULL | NULL |
| 1005 | Project 1005 | 2014-02-10 | 2014-02-10 | 0 |
| 1005 | Project 1005 | 2014-02-11 | 2014-02-11 | 0 |
| 1005 | Project 1005 | 2014-02-12 | 2014-02-12 | 0 |
| 1005 | Project 1005 | 2014-02-13 | NULL | NULL |
| 1005 | Project 1005 | 2014-02-14 | NULL | NULL |
| 1005 | Project 1005 | 2014-02-18 | NULL | NULL |
| 1005 | Project 1005 | 2014-02-19 | NULL | NULL |
| 1005 | Project 1005 | 2014-02-20 | 2014-02-20 | 0 |
| 1005 | Project 1005 | 2014-02-21 | 2014-02-21 | 0 |
| 1005 | Project 1005 | 2014-02-24 | 2014-02-24 | 0 |
| 1005 | Project 1005 | 2014-02-25 | 2014-02-25 | 0 |
| 1005 | Project 1005 | 2014-02-26 | NULL | NULL |
| 1005 | Project 1005 | 2014-02-27 | NULL | NULL |
| 1005 | Project 1005 | 2014-02-28 | NULL | NULL |
+------------+--------------+--------------+-------------+-----------+
谢谢大家的帮助 很抱歉,报告表不包含“报告日期”列。我在发布示例架构时意外地删除了它。我已经编辑了示例架构,以显示它现在在那里。您的查询结果是什么?为什么要正确连接到日历表?我得到一个空的结果集。我需要加入日历表,以便确定创建报告的所有日期。我不认为需要正确的加入,为什么要包括所有日历记录而不包含匹配的报告记录?您可以尝试拆分查询并检查子查询的结果:A:“没有加入且仅包含日期的日历”,B:“没有联接和完整where语句的日历”,C:“报表联接日历”。。。