【问题标题】:MySQL aggregate data IN, OUT timesMySQL 聚合数据 IN、OUT 时间
【发布时间】:2015-03-03 01:27:04
【问题描述】:

我在桌子上是这样的:

ID | UID | ACTION | URL | TIMESTAMP

在哪里...

ID - primary key
UID - user id
ACTION - IN or OUT
URL - action URL
TIMESTAMP - action TIMESTAMP

如何通过一次查询聚合所有数据?

我的意思是...作为输出,我想要带有UIDURLTOTAL_TIME 的表格,其中TOTAL_TIME 将是给定URL 的INOUT 之间所有时间的总和。 .

我尝试了一些自定义函数,但没有运气......

示例输入(时间戳简化以显示我的意思):

1|13|IN|http://www.gógle.koń|1
2|13|OUT|http://www.gógle.koń|5
...
13454|13|IN|http://www.gógle.koń|550
...
13465|13|OUT|http://www.gógle.koń|600
...
243252|13|IN|http://www.pr0nstaff.meh|tiny_leg_finger|1200
...
245431|13|OUT|http://www.pr0nstaff.meh/tiny_leg_finger|2200

请注意,IN - OUT 中的一个 URL 可能会被 ININ - OUTOUT 或其他的 OUT 破坏 ...所以我们不能在不检查站点匹配的情况下简单地从 IN 计数到 OUT。

例如输入(UUID = 13)的输出应该是:

13|www.gógle.koń|14
13|http://www.pr0nstaff.meh/tiny_leg_finger|1000

【问题讨论】:

  • 主要问题是速度,而不是解决方案本身......那里有大约 30GB 的数据......

标签: mysql sql datetime select group-by


【解决方案1】:

试试这个,但我不放心,如果 IN/OUT 并不总是双倍的。所以请检查..

CREATE TABLE test1 (
 id INT NOT NULL,
 uid INT NOT NULL,
 action VARCHAR(3),
 url varchar(100),
 timestamp1 TIMESTAMP
);

INSERT INTO test1 VALUES
( 1 , 13 , 'IN', 'www.go.com', '2015-01-07 08:00:00'),
( 2 , 13 , 'OUT', 'www.go.com', '2015-01-07 09:00:00'),
( 3 , 14 , 'IN', 'www.go2.com', '2015-01-07 08:30:00'),
( 4 , 14 , 'OUT', 'www.go2.com', '2015-01-07 09:00:00'),
( 5 , 15 , 'IN', 'www.go3.com', '2015-01-07 09:00:00'),
( 6 , 16 , 'OUT', 'www.go3.com', '2015-01-07 09:00:00');


SELECT i.uid,i.url,SUM(TIMESTAMPDIFF(minute, i.timestamp1, o.timestamp1)) AS diff_hour
FROM   (SELECT id,uid,url,timestamp1
        FROM   test1
        WHERE  action = 'IN') i
JOIN (SELECT id,uid,url,timestamp1
        FROM   test1
       WHERE  action = 'OUT') o
  ON i.uid = o.uid
 AND i.url = o.url
 AND i.id < o.id
GROUP  BY i.uid,i.url
ORDER  BY i.uid,i.url;

【讨论】:

  • 有可能有IN没有OUT,不确定有OUT没有IN,但可能不会……这种情况下,再一个IN之后,应该取最近一个IN的日期第一出。例如 IN IN OUT 应该采用最新的 IN 和第一个 OUT,但 IN OUT OUT IN OUT 应该采用第一个 IN,第一个 OUT,跳过没有 IN 的 OUT,然后计算最后一个 IN OUT 对。有点复杂,但在这种情况下很自然。
【解决方案2】:

试试这个:

SELECT UID, URL, TIMESTAMPDIFF(HOUR, InTime, OutTime) AS TOTAL_TIME 
FROM (SELECT UID, URL, 
             MAX(CASE WHEN ACTION = 'IN' THEN TIMESTAMP ELSE NULL END) InTime, 
             MAX(CASE WHEN ACTION = 'OUT' THEN TIMESTAMP ELSE NULL END) OutTime
      FROM tableA 
      GROUP BY UID, URL
    ) AS A;

【讨论】:

  • 不确定它是否适合这样的情况: IN1 www.com OUT1 www.com IN2 www.com OUT2 www.com ... 从 IN1 计数到 OUT2,不会是吗?
  • 已编辑问题以满足您的需求,谢谢
猜你喜欢
  • 1970-01-01
  • 2018-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-23
  • 2016-06-14
相关资源
最近更新 更多