簡體   English   中英

SQL 查詢-選擇一個月中每一天的第一條和最后一條記錄

[英]SQL query - selecting first and last record of each day in a month

Mysql 5.7.30:我有兩個表:

項目projectID,timeNeeded

注冊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  

此要求的棘手部分是只有 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

請參閱演示
結果:

| registrationID | timeNeeded |
| -------------- | ---------- |
| reg1           | 50         |
| reg2           | 50         |
| reg3           | 30         |
| reg6           | 20         |
| reg7           | 30         |
| reg7           | 30         |
| reg8           | 50         |
| reg8           | 50         |
| reg9           | 30         |
| reg10          | 20         |

我會通過使用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 來確定每天的第一個和最后一個。

是一個 db<>fiddle。

由於您的表格缺少標題,因此我寫得有點抽象。

select * 來自注冊,按 timestamp_col desc 限制排序 1;

select * 來自注冊,按 timestamp_col 限制排序 1;

這兩個查詢應該為您提供第一個和最后一個注冊。 如果您只有一個注冊,那么這兩個查詢將返回相同的記錄。 這將滿足您的需求。

我忽略了與 Project 表的連接,假設您知道如何連接兩個表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM