没有一种行类型的多个日期之间的小时总和
Sum of hours between multiple dates without one row type
我需要把时间加起来,减去状态为“STOP”时的时间。我可以进行 SQL 查询还是需要合并 SQL + PHP?我得到了这样一个数据库。状态可以重复
MariaDB 10.5.11,
PHP7.4.5
ID Date Status
1 2020.11.02 15:00 New
1 2020.11.02 15:00 New_Step
1 2020.11.02 15:05 Start
1 2020.11.02 15:05 Stop
1 2020.11.02 15:10 Start
1 2020.11.02 15:15 Transferred
1 2020.11.02 15:20 Stop
1 2020.11.02 16:25 End
2 2020.11.02 16:00 New
2 2020.11.02 16:00 Start
2 2020.11.02 16:05 Stop
2 2020.11.02 16:10 Start
2 2020.11.02 16:15 Stop
2 2020.11.02 16:20 Start
2 2020.11.02 16:25 New_Step
3 2020.11.02 16:30 Transferred
2 2020.11.02 16:35 End
我需要得到这个结果
ID SumTime
1 15 min
2 25 min
我需要向此查询添加新状态“已转移且 New_Step”
SELECT t1.ID, SUM(TIMESTAMPDIFF(MINUTE,t1.`Date`,t2.`Date`)) complsum
FROM (SELECT *,ROW_NUMBER() OVER (PARTITION BY `ID` ORDER BY `Date` ASC) AS row_num
FROM table1 WHERE `Status` = 'Start') t1
INNER JOIN (SELECT *,ROW_NUMBER() OVER (PARTITION BY `ID` ORDER BY `Date` ASC) AS row_num
FROM table1 WHERE `Status` IN ('Stop','End')) t2
ON t1.ID = t2.ID AND t1.`row_num` = t2.`row_num`
GROUP BY t1.ID
我不明白其中的逻辑,但也许你需要在
WITH cte AS (SELECT ID, `Date`
FROM test
GROUP BY ID, `Date`
-- remove timepoint where status is 'Stop' for at least one row
HAVING !SUM(Status = 'Stop'))
SELECT ID,
-- Calculate points amount and multiply by 5, adjust points to ranges between points
CONCAT(5 * COUNT(`Date`) - 5, ' min')
FROM cte
GROUP BY id;
?
您想计算所有开始状态不是“停止”的间隔。您可以只使用 lead()
和日期算法:
select id, sum(timestampdiff(minute, date, lead_date)) sumtime
from (
select t.*, lead(date) over(partition by id order by date) lead_date
from mytable t
) t
where status <> 'Stop'
group by id
请注意,要使其始终如一地工作,您需要每个 date
都是唯一的 - 否则事件的顺序未定义重复 - 或者,至少,您需要另一个标准来打破日期关系,例如 auto-incrementing 主键。
这里有一个demo on DB Fiddle演示了查询是如何工作的,在子查询的order by
中添加了一个主键。
我需要把时间加起来,减去状态为“STOP”时的时间。我可以进行 SQL 查询还是需要合并 SQL + PHP?我得到了这样一个数据库。状态可以重复
MariaDB 10.5.11,
PHP7.4.5
ID Date Status
1 2020.11.02 15:00 New
1 2020.11.02 15:00 New_Step
1 2020.11.02 15:05 Start
1 2020.11.02 15:05 Stop
1 2020.11.02 15:10 Start
1 2020.11.02 15:15 Transferred
1 2020.11.02 15:20 Stop
1 2020.11.02 16:25 End
2 2020.11.02 16:00 New
2 2020.11.02 16:00 Start
2 2020.11.02 16:05 Stop
2 2020.11.02 16:10 Start
2 2020.11.02 16:15 Stop
2 2020.11.02 16:20 Start
2 2020.11.02 16:25 New_Step
3 2020.11.02 16:30 Transferred
2 2020.11.02 16:35 End
我需要得到这个结果
ID SumTime
1 15 min
2 25 min
我需要向此查询添加新状态“已转移且 New_Step”
SELECT t1.ID, SUM(TIMESTAMPDIFF(MINUTE,t1.`Date`,t2.`Date`)) complsum
FROM (SELECT *,ROW_NUMBER() OVER (PARTITION BY `ID` ORDER BY `Date` ASC) AS row_num
FROM table1 WHERE `Status` = 'Start') t1
INNER JOIN (SELECT *,ROW_NUMBER() OVER (PARTITION BY `ID` ORDER BY `Date` ASC) AS row_num
FROM table1 WHERE `Status` IN ('Stop','End')) t2
ON t1.ID = t2.ID AND t1.`row_num` = t2.`row_num`
GROUP BY t1.ID
我不明白其中的逻辑,但也许你需要在
WITH cte AS (SELECT ID, `Date`
FROM test
GROUP BY ID, `Date`
-- remove timepoint where status is 'Stop' for at least one row
HAVING !SUM(Status = 'Stop'))
SELECT ID,
-- Calculate points amount and multiply by 5, adjust points to ranges between points
CONCAT(5 * COUNT(`Date`) - 5, ' min')
FROM cte
GROUP BY id;
?
您想计算所有开始状态不是“停止”的间隔。您可以只使用 lead()
和日期算法:
select id, sum(timestampdiff(minute, date, lead_date)) sumtime
from (
select t.*, lead(date) over(partition by id order by date) lead_date
from mytable t
) t
where status <> 'Stop'
group by id
请注意,要使其始终如一地工作,您需要每个 date
都是唯一的 - 否则事件的顺序未定义重复 - 或者,至少,您需要另一个标准来打破日期关系,例如 auto-incrementing 主键。
这里有一个demo on DB Fiddle演示了查询是如何工作的,在子查询的order by
中添加了一个主键。