SQL获取表中另一列分组的给定日期之间的日期范围

问题描述 投票:0回答:3

在此表中-

----------------------------------------------
ID  | user   | type   | timestamp
----------------------------------------------
1   | 1      | 1      | 2019-02-08 15:00:00
2   | 1      | 3      | 2019-02-15 15:00:00
3   | 1      | 2      | 2019-03-06 15:00:00
4   | 2      | 3      | 2019-02-01 15:00:00
5   | 2      | 1      | 2019-02-06 15:00:00
6   | 3      | 1      | 2019-01-10 15:00:00
7   | 3      | 4      | 2019-02-08 15:00:00
8   | 3      | 3      | 2019-02-24 15:00:00
9   | 3      | 2      | 2019-03-04 15:00:00
10  | 3      | 3      | 2019-03-05 15:00:00

我需要找到在给定的天数范围内每个用户处于特定类型的天数。

例如:对于给定范围2019-02-012019-03-04,输出应为

--------------------------------
user   | type   | No. of days
--------------------------------
1      | 1      | 7
1      | 3      | 17
2      | 3      | 6
3      | 1      | 29
2      | 4      | 16
2      | 3      | 8

用户可以随时在类型之间进行切换,但是我需要捕获所有这些切换以及用户使用某种类型的天数。我目前通过获取所有值并在JS中手动过滤内容来解决此问题。有什么办法可以通过SQL查询做到这一点?我使用MYSQL 5.7.23。

mysql sql date group-by datediff
3个回答
0
投票

使用lead(),然后使用datediff()sum(),以及许多日期比较:

select user, type,
       sum(datediff( least(next_ts, '2019-03-04'), greatest(timestamp, '2019-02-01'))
from (select t.*,
             lead(timestamp, 1, '2019-03-04') over (partition by user order by timestamp) as next_ts
      from t
     ) t
where next_ts >= '2019-02-01' and
      timestamp <= '2019-03-04'
group by user, type;

0
投票

这应该给您您想要的东西:

select id, user, type, time_stamp, (
    select to_days(coalesce(min(time_stamp),current_timestamp())) - to_days(t1.time_stamp)
    from table1 as t2
    where t2.user = t1.user 
    and   t2.time_stamp > t1.time_stamp
    ) as days
from table1 as t1
order by id;

在这里玩小提琴:http://sqlfiddle.com/#!9/347ab5/17


0
投票

您得到的不是您想要的,但它是准确的

SELECT 
  `user`
  ,`type`
  ,dategone `No. of days`
  FROM
(SELECT 
  `type`,
  IF(@id = `user`,DATEDIFF(`timestamp` , @days), -1) dategone #
  ,@id := `user`  `user`
  ,@days := `timestamp` 
 FROM
   (SELECT 
      `D`, `user`, `type`, `timestamp`
    From table1
    ORDER BY `user` ASC, `timestamp`  ASC) a
   , (SELECT @days :=0) b, (SELECT @id :=0) c) d
WHERE dategone > -1;
CREATE TABLE table1 (
  `D` INTEGER,
  `user` INTEGER,
  `type` INTEGER,
  `timestamp` VARCHAR(19)
);

INSERT INTO table1
  (`D`, `user`, `type`, `timestamp`)
VALUES
  ('1', '1', '1', '2019-02-08 15:00:00'),
  ('2', '1', '3', '2019-02-15 15:00:00'),
  ('3', '1', '2', '2019-03-06 15:00:00'),
  ('4', '2', '3', '2019-02-01 15:00:00'),
  ('5', '2', '1', '2019-02-06 15:00:00'),
  ('6', '3', '1', '2019-01-10 15:00:00'),
  ('7', '3', '4', '2019-02-08 15:00:00'),
  ('8', '3', '3', '2019-02-24 15:00:00'),
  ('9', '3', '2', '2019-03-04 15:00:00'),
  ('10', '3', '3', '2019-03-05 15:00:00');
✓✓
SELECT 
  `user`
  ,`type`
  ,dategone `No. of days`
  FROM
(SELECT 
`type`,
IF(@id = `user`,DATEDIFF(`timestamp` , @days), -1) dategone #
,@id := `user`  `user`
,@days := `timestamp` 
FROM
(SELECT 
  `D`, `user`, `type`, `timestamp`
From table1
ORDER BY `user` ASC, `timestamp`  ASC) a, (SELECT @days :=0) b, (SELECT @id :=0) c) d
WHERE dategone > -1;
用户|类型天数---: ---: ----------:1 | 3 | 71 | 2 | 192 | 1 | 53 | 4 | 293 | 3 | 163 | 2 | 83 | 3 | 1个

db <>小提琴here

© www.soinside.com 2019 - 2024. All rights reserved.