SQL查询-选择一个月中每一天的第一条记录和最后一条记录

时间:2020-07-28 20:48:24

标签: mysql sql

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  

3 个答案:

答案 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表的联接。