[英]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.