MySQL 5.7.30:我有两个表:
项目:项目ID,需要时间
注册: registrationID,projectID,startDateTime
我想要实现的目标: 对于当前月份(基于startDateTime),我想通过选择该月每一天的第一条记录和最后一条记录来了解“ timeNeeded”。 如果一天只有1条记录,它仍应计数两次 。
例如,如果一天有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
答案 0 :(得分: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
请参见demo。
结果:
| registrationID | timeNeeded |
| -------------- | ---------- |
| reg1 | 50 |
| reg2 | 50 |
| reg3 | 30 |
| reg6 | 20 |
| reg7 | 30 |
| reg7 | 30 |
| reg8 | 50 |
| reg8 | 50 |
| reg9 | 30 |
| reg10 | 20 |
答案 1 :(得分: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
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来确定每天的第一和最后一天。
Here是db <>小提琴。
答案 2 :(得分:0)
由于您的表缺少标题,因此写的有点抽象。
从注册中按timestamp_col desc限制1选择*;
和
从注册中按* timestamp_col限制1选择*;
这两个查询应为您提供第一个和最后一个注册。如果您只有一个注册,则两个查询都将返回相同的记录。这将满足您的需求。
假设您知道如何联接两个表,我将忽略与Project表的联接。