Mysql SQL查询-选择一个月内每天的第一条和最后一条记录
Mysql 5.7.30:我有两个表: 项目:项目,所需时间 注册:注册ID、projectID、startDateTime 我想要达到的目标: 对于当前月份(基于startDateTime),我希望通过选择该月份每天的第一个和最后一个记录来了解“需要的时间”如果一天只有一条记录,它仍应计数两次 例如,如果一天有4个注册,我只想包括这4个注册中的第一个和最后一个 我有点不确定如何开始,我想有多种方法可以实现这一点。速度并不重要,只要它比我的第一个想法好;使用多个查询和PHP来处理它 样本数据和想要的结果:Mysql SQL查询-选择一个月内每天的第一条和最后一条记录,mysql,sql,Mysql,Sql,Mysql 5.7.30:我有两个表: 项目:项目,所需时间 注册:注册ID、projectID、startDateTime 我想要达到的目标: 对于当前月份(基于startDateTime),我希望通过选择该月份每天的第一个和最后一个记录来了解“需要的时间”如果一天只有一条记录,它仍应计数两次 例如,如果一天有4个注册,我只想包括这4个注册中的第一个和最后一个 我有点不确定如何开始,我想有多种方法可以实现这一点。速度并不重要,只要它比我的第一个想法好;使用多个查询和PHP来处理它 样本数据和想
Project table:
project1 50
project2 20
project3 30
Registation table: (hour:minute hidden)
reg1 project1 2020-07-01
reg2 project1 2020-07-01
reg3 project3 2020-07-02
reg4 project3 2020-07-02
reg5 project2 2020-07-02
reg6 project2 2020-07-02
reg7 project3 2020-07-03
reg8 project1 2020-07-04
reg9 project3 2020-07-05
reg10 project2 2020-07-05
Result (projects.timeNeeded for first and last of each day):
reg1 50
reg2 50
reg3 30
reg6 20
reg7 30
reg7 30
reg8 50
reg8 50
reg9 30
reg10 20
由于您的表缺少标题,我写了一点摘要 从注册中选择*按时间戳排序\u col desc limit 1 及 从注册中选择*按时间戳排序\u col limit 1 这两个查询将为您提供第一次和最后一次注册。如果您只有一个注册,那么两个查询将返回相同的记录。这将满足你的需要
我忽略了与项目表的连接,假设您知道如何连接两个表。由于您的表缺少标题,我写了一点摘要 从注册中选择*按时间戳排序\u col desc limit 1 及 从注册中选择*按时间戳排序\u col limit 1 这两个查询将为您提供第一次和最后一次注册。如果您只有一个注册,那么两个查询将返回相同的记录。这将满足你的需要
假设您知道如何连接两个表,我忽略了与项目表的连接。此要求的棘手部分是只有1个注册的日期的两行,这就是我使用UNION ALL的原因。
需要聚合以获取每天的第一个和最后一个
startDateTime
,并最终加入:
select r.registrationID, p.timeNeeded
from (
select registrationID, projectID, startDateTime
from Registration
union all
select max(registrationID), max(projectID), max(startDateTime)
from Registration
group by date(startDateTime)
having count(*) = 1
) r
inner join (
select date(startDateTime) date,
min(startDateTime) min_date,
max(startDateTime) max_date
from Registration
where date_format(startDateTime, "%Y-%m") = date_format(current_date, "%Y-%m")
group by date
) t on r.startDateTime in (t.min_date, t.max_date)
inner join Project p on p.projectID = r.projectID
order by r.startDateTime
请参阅。结果:
此要求的棘手部分是只有1个注册的日期的两行,这就是我使用UNION ALL的原因。
需要聚合以获取每天的第一个和最后一个
startDateTime
,并最终加入:
select r.registrationID, p.timeNeeded
from (
select registrationID, projectID, startDateTime
from Registration
union all
select max(registrationID), max(projectID), max(startDateTime)
from Registration
group by date(startDateTime)
having count(*) = 1
) r
inner join (
select date(startDateTime) date,
min(startDateTime) min_date,
max(startDateTime) max_date
from Registration
where date_format(startDateTime, "%Y-%m") = date_format(current_date, "%Y-%m")
group by date
) t on r.startDateTime in (t.min_date, t.max_date)
inner join Project p on p.projectID = r.projectID
order by r.startDateTime
请参阅。结果:
我会使用
union all
,每天第一次记录一次,最后一次记录一次:
select r.*, p.timeneeded
from Registration r join
Project p
on r.projectid = p.projectid
where extract(year_month from r.startDateTime) = extract(year_month from now()) and
r.registrationID = (select r2.registrationID
from Registration r2
where date(r2.startDateTime) = date(r.startDatetime)
order by r2.registrationID
limit 1
)
union all
select r.*, p.timeneeded
from Registration r join
Project p
on r.projectid = p.projectid
where extract(year_month from r.startDateTime) = extract(year_month from now()) and
r.registrationID = (select r2.registrationID
from Registration r2
where date(r2.startDateTime) = date(r.startDatetime)
order by r2.registrationID desc
limit 1
)
order by registrationID;
注意:你们的日期都一样。列的名称表明可能有时间成分,但您的问题没有时间成分。因此,它使用注册id来确定每天的第一个和最后一个
是一个数据小提琴。我会使用
联合所有
,每天第一次记录一次,最后一次记录一次:
select r.*, p.timeneeded
from Registration r join
Project p
on r.projectid = p.projectid
where extract(year_month from r.startDateTime) = extract(year_month from now()) and
r.registrationID = (select r2.registrationID
from Registration r2
where date(r2.startDateTime) = date(r.startDatetime)
order by r2.registrationID
limit 1
)
union all
select r.*, p.timeneeded
from Registration r join
Project p
on r.projectid = p.projectid
where extract(year_month from r.startDateTime) = extract(year_month from now()) and
r.registrationID = (select r2.registrationID
from Registration r2
where date(r2.startDateTime) = date(r.startDatetime)
order by r2.registrationID desc
limit 1
)
order by registrationID;
注意:你们的日期都一样。列的名称表明可能有时间成分,但您的问题没有时间成分。因此,它使用注册id来确定每天的第一个和最后一个
是一个dbfiddle。请提供示例数据和所需结果。@GordonLinoff我已经添加了示例。您的MySql版本是什么?@forpas MySql版本5.7.30
timeNeeded
对于'reg6'
来说,结果应该是20。请提供示例数据和所需结果。@GordonLinoff我已经添加了示例。您的版本是什么MySql?@forpas MySql版本5.7.30timeNeeded
for'reg6'
的结果应该是20。谢谢,但这差不多是我自己所能做到的。我想知道的是如何在一个月的所有日子里都这样做,并将结果结合起来。Union all或select SUBQUERES是执行此操作的方法吗?通常在主查询中使用子查询的结果时使用子查询。在您的情况下,联合是好的,因为您不依赖于主查询的子查询结果。谢谢,但这差不多是我自己努力做到的。我想知道的是如何在一个月的所有日子里都这样做,并将结果结合起来。Union all或select SUBQUERES是执行此操作的方法吗?通常在主查询中使用子查询的结果时使用子查询。在您的情况下,联合是好的,因为您不依赖于主查询的子查询结果。非常感谢,这比我预想的要复杂得多!我相信你的查询是正确的,但在我在实际项目中实现它之后,我得到了同一日期的4条记录,在这种情况下,只有两个注册。(在本例中,reg9和reg10将显示4次)。我有点不确定在联合之后选择的目的是什么?你有重复的startDateTimes吗?不应该有重复的startDateTimes。我想它可能会为每个注册选择2个。projectID?你能用小提琴复制这个问题吗?非常感谢,这比我预期的要复杂!我相信你的查询是正确的,但在我在实际项目中实现它之后,我得到了同一日期的4条记录,在这种情况下,只有两个注册。(在本例中,reg9和reg10将显示4次)。我有点不确定在联合之后选择的目的是什么?你有重复的startDateTimes吗?不应该有重复的startDateTimes。我想它可能会为每个注册选择2个。projectID?你能用小提琴重现这个问题吗?我写道hh:mm是隐藏的,但我想我应该说得更清楚:是的,它需要使用startDatetime字段来确定哪一天是第一天/最后一天。我试图用startDatetime替换order by,但这一天产生了4条记录……我写道hh:mm是隐藏的,但我想我应该更清楚:是的,它需要使用startDatetime字段来确定哪一条是当天的第一条/最后一条。我试图用startDatetime替换order by,但这为o生成了4条记录