+----------+--------------+-------------------------+
| ticketid | ticketpostid | date |
+----------+--------------+-------------------------+
| 1387935 | 3147808 | 2012-09-17 13:33:01 |
| 1387935 | 3147812 | 2012-09-17 13:33:41 |
| 1387938 | 3147818 | 2012-09-17 13:35:01 |
| 1387938 | 3148068 | 2012-09-17 13:37:01 |
| 1387938 | 3148323 | 2012-09-17 14:47:01 |
| 1387939 | 3147820 | 2012-09-17 13:36:01 |
| 1387939 | 3147834 | 2012-09-17 13:36:25 |
| 1387939 | 3147851 | 2012-09-17 13:41:01 |
| 1387939 | 3147968 | 2012-09-17 13:59:06 |
| 1387939 | 3147996 | 2012-09-17 14:03:01 |
这是我写的查询的结果。有两个和两个以上的行具有相同的ticketid。我需要找到每个ticketid中前两个日期之间的时差
实施例
+----------+--------------+-------------------------+
| ticketid | ticketpostid | date |
+----------+--------------+-------------------------+
| 1387935 | 3147808 | 2012-09-17 13:33:01 |
| 1387935 | 3147812 | 2012-09-17 13:33:41 |
| 1387938 | 3147818 | 2012-09-17 13:35:01 |
| 1387938 | 3148068 | 2012-09-17 13:37:01 |
| 1387939 | 3147820 | 2012-09-17 13:36:01 |
| 1387939 | 3147834 | 2012-09-17 13:36:25 |
结果;
+----------+--------------+
| ticketid |time diff(sec)|
+----------+--------------+
| 1387935 | 40 |
| 1387938 | 120 |
| 1387939 | 24 |
你能告诉我怎么做吗?
感谢。
答案 0 :(得分:14)
对于PostgreSQL,我认为您希望lag
window function比较行;它比自连接和过滤器更有效。这不适用于MySQL,因为它似乎仍然不支持标准的SQL:2003窗口函数;见下文。
要仅查找最低的两个,您可以在dense_rank
上使用ticketid
窗口函数,然后过滤结果以仅返回dense_rank() = 2
的行,即第二个来自的行 - 最低时间戳,其中lag()
将生成时间戳最短的行。
请参阅this SQLFiddle,其中显示了示例DDL和输出。
SELECT ticketid, extract(epoch from tdiff) FROM (
SELECT
ticketid,
ticketdate - lag(ticketdate) OVER (PARTITION BY ticketid ORDER BY ticketdate) AS tdiff,
dense_rank() OVER (PARTITION BY ticketid ORDER BY ticketdate) AS rank
FROM Table1
ORDER BY ticketid) x
WHERE rank = 2;
我使用ticketdate
作为日期列的名称,因为date
是列的一个可怕名称(它是数据类型名称),不应该使用;它必须在许多情况下用双引号才能工作。
便携式方法可能是其他人发布的自我加入方式。上面的窗口函数方法也可能适用于Oracle,但在MySQL中似乎没有。据我所知,它不支持SQL:2003窗口函数。
如果您SET sql_mode = 'ANSI'
并使用timestamp
而不是timestamp with time zone
,架构定义将适用于MySQL。似乎窗口功能不会; MySQL在OVER
子句上扼杀了。请参阅this SQLFiddle。
答案 1 :(得分:2)
尝试此查询 -
INSERT INTO ticket_post(ticketid, ticketpostid, date) VALUES
(1387935, 3147808, '2012-09-17 13:33:01'),
(1387935, 3147812, '2012-09-17 13:33:41'),
(1387938, 3147818, '2012-09-17 13:35:01'),
(1387938, 3148068, '2012-09-17 13:37:01'),
(1387938, 3148323, '2012-09-17 14:47:01'),
(1387939, 3147820, '2012-09-17 13:36:01'),
(1387939, 3147834, '2012-09-17 13:36:25'),
(1387939, 3147851, '2012-09-17 13:41:01'),
(1387939, 3147968, '2012-09-17 13:59:06'),
(1387939, 3147996, '2012-09-17 14:03:01');
SELECT
ticketid,
TIME_TO_SEC(TIMEDIFF((
SELECT t.date FROM ticket_post t WHERE t.ticketid = t1.ticketid AND t.date > t1.date ORDER BY t.date LIMIT 1),
MIN(date)
)) diff FROM ticket_post t1
GROUP BY ticketid;
+----------+------+
| ticketid | diff |
+----------+------+
| 1387935 | 40 |
| 1387938 | 120 |
| 1387939 | 24 |
+----------+------+
答案 2 :(得分:1)
select
ticketid
,time_to_sec(timediff(t2.date, t1.date)) as timediff
from table t1
join table t2 on t1.ticketid=t2.ticketid and t1.ticketpostid<t2.ticketpostid