首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >计算日期时间MYSQL

问计算日期时间MYSQL
EN

Stack Overflow用户
提问于 2014-05-02 21:38:54
回答 3查看 50关注 0票数 0

我需要一个SQL命令来完成这个任务。我的来源数据是:

日期;W1 2014-05-02 :00:10;2500 2014-05-02 :00:11;2800 2014-05-02 :00:12;2900 2014-05-02 :00:13;1000 2014-05-02 :00:14;1000 2014-05-02 :00:10;1000 2014-05-02 :00:11;1000 2014-05-02 :00:12;1000 2014-05-02 :00:13;1000 2014-05-02 :00:14;1000 2014-05-02 :00:10;3000 2014-05-02 :00:11;2500 2014-05-02 :00:12;2000 2014-05-02 :00:13;2500 2014-05-02 :00:14;2800

因此,我现在想要的是W1高于2000年的日期差

应该是:

2014-05-02 :00:10 -> 2014-05-02 :00:12 2014-05-02 08:00:10 -> 2014-05-02 :00:14

我知道我可以用php来完成这个任务,但是是否有一种方法可以用sql命令来完成呢?

谢谢你的帮助

编辑1:或者说我至少得到了这样的东西:

2014-05-02 03:00:10 2014-05-02 03:00:12 2014-05-02 08:00:10 2014-05-02 03:00:14

每次超过1秒之间。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-05-02 21:56:22

我想,如果按日期和小时(分钟除外)对行进行分组,然后在存在多个时间的情况下计数不同的日期,这将非常简单,这满足了秒差条件,因此可以使用min/max从'%Y-%m-%d %H'组获取日期。

代码语言:javascript
复制
SELECT 
MIN(`Date`) `min_date`,
MAX(`Date`) `max_date`,
CONCAT(MIN(`Date`)  ,'->',MAX(`Date`) ) `concatenated`,
COUNT(DISTINCT `Date`) `different_dates`
FROM t
WHERE `W1` > 2000
GROUP BY DATE_FORMAT(`Date`,'%Y-%m-%d %H')
HAVING different_dates >1 

小提琴演示

票数 0
EN

Stack Overflow用户

发布于 2014-05-02 21:48:35

我认为create table w1data (atime DATETIME, value int)和LOAD DATA INFILE很容易。

在此之后,您有一个表,它可以由

代码语言:javascript
复制
select * from w1data where value > 2000

这不是你想要的,而是一个好的开始。

现在要比较select的两个不同行,这需要一个kond of a技巧:

代码语言:javascript
复制
set @lastrow = NULL;
select (if(@lastrow is NULL, NULL, unix_timestamp(atime) - unix_timestamp(@lastrow)) as diff_seconds, @lastrow := atime as dummy
from (select distinct atime from w1data where value > 2000 order by atime)
;

编辑:如果您想要的是时间而不是秒,只需使用(EDIT2:when和限制词when替换) (EDIT3: instead当然需要一个别名)

代码语言:javascript
复制
set @lastrow = NULL;
select concat(@lastrow, " -> ", atime) as length, (@lastrow := atime) as dummy
from (select distinct atime from w1data where value > 2000 order by atime) as dat_sel
;
票数 0
EN

Stack Overflow用户

发布于 2014-05-02 22:31:55

这里有一种方法可以得到指定的结果,

代码语言:javascript
复制
SELECT CONCAT(
         SUBSTRING_INDEX(SUBSTRING_INDEX(t.state,'#',2),'#',-1)
       ,' -> ',
         SUBSTRING_INDEX(SUBSTRING_INDEX(t.state,'#',3),'#',-1)
       ) AS `r`
  FROM ( SELECT IF(@state+0,
                  IF(w1>2000, NULL, CONCAT(@state := 0,'#', @start, '#', @prev_dt , '#')),
                  IF(w1>2000, CONCAT(@state := 1,'#',@start := dt,'#'), NULL)
                ) AS state
              , @prev_dt := m.dt AS dt
           FROM mydata m
          CROSS
           JOIN (SELECT @start := '', @prev_dt := '', @state := '0') i
          ORDER BY m.dt, m.w1 
       ) t
 WHERE t.state LIKE '0#%'
   AND SUBSTRING_INDEX(SUBSTRING_INDEX(t.state,'#',3),'#',-1) 
     > SUBSTRING_INDEX(SUBSTRING_INDEX(t.state,'#',2),'#',-1)

这使用MySQL用户定义的变量“保存”前几行的值。内联视图查询(别名为t)负责检查w1的值,并确定范围是否已经启动或结束。

外部查询只选择范围标记为"ended“的行。(这只返回已结束的范围,也就是说,如果最后一行的值为w1>2000,则范围尚未标记为and,包含该行的范围将被省略。

添加一个额外的“跟踪”记录(即"UNION ALL SELECT MAX(n.dt+INTERVAL 1 SECOND AS dt, 0 AS w1 FROM mydata n"将解决这个问题)。或者,列表可以按反向顺序处理,从最近的日期回到最早的日期,反转检查,然后省略一个未启动的“最早”范围。)

这种方法适用于任何长度的“范围”,其跨度为几秒,或多小时或数天(只要范围结束)。

安装测试用例:

代码语言:javascript
复制
CREATE TABLE mydata (dt DATETIME, w1 INT UNSIGNED) ENGINE=MYISAM;

CREATE INDEX mydata_IX1 ON mydata (dt, w1);

INSERT INTO mydata (dt, w1) VALUES
('2014-05-02 03:00:10','2500')
,('2014-05-02 03:00:11','2800')
,('2014-05-02 03:00:12','2900')
,('2014-05-02 03:00:13','1000')
,('2014-05-02 03:00:14','1000')
,('2014-05-02 05:00:10','1000')
,('2014-05-02 05:00:11','1000')
,('2014-05-02 05:00:12','1000')
,('2014-05-02 05:00:13','1000')
,('2014-05-02 05:00:14','1000')
,('2014-05-02 08:00:10','3000')
,('2014-05-02 08:00:11','2500')
,('2014-05-02 08:00:12','2000')
,('2014-05-02 08:00:13','2500')
,('2014-05-02 08:00:14','2800');
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23437377

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档