基于条件的行之间的时间差

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

不是真正的 SQL 专家,我在弄清楚如何做这件事时遇到了问题。

有这样一张桌子:

ID 留言 时间戳 用户
1 你好 2022-08-01 10:00:00 A
1 你好吗? 2022-08-01 10:00:05 A
1 你好 2022-08-01 10:00:10
1 我没事 2022-08-01 10:00:12
1 很高兴知道 2022-08-01 10:00:15 A
1 再见 2022-08-01 10:00:25
2 你好 2022-08-01 10:02:50 A
2 2022-08-01 10:03:50

需要计算每次A发消息后B用户回复的时间差

预期结果会是这样

ID 区别
1 5
1 10
2 60

尝试使用 Lead 函数获取下一个所需的时间戳,但我没有得到预期的结果 有什么提示或建议吗?

谢谢

sql vertica
3个回答
0
投票

即使它已经被回答 - 这是 Vertica 的 MATCH() 子句的一个很好的用例。寻找由

sender = 'A'
后跟
sender = 'B'
组成的模式。 你得到一个模式 id,然后你可以按其他东西加上模式 id 来分组以获得最大时间戳和最小时间戳。

另请注意,我重命名了“user”和“timestamp”,因为它们是保留字...

-- your input, don't use in final query
indata(ID,Message,ts,Usr) AS (
          SELECT 1,'Hello'       ,TIMESTAMP '2022-08-01 10:00:00','A'
UNION ALL SELECT 1,'How are you?',TIMESTAMP '2022-08-01 10:00:05','A'
UNION ALL SELECT 1,'Hello there' ,TIMESTAMP '2022-08-01 10:00:10','B'
UNION ALL SELECT 1,'I am okay'   ,TIMESTAMP '2022-08-01 10:00:12','B'
UNION ALL SELECT 1,'Good to know',TIMESTAMP '2022-08-01 10:00:15','A'
UNION ALL SELECT 1,'Bye'         ,TIMESTAMP '2022-08-01 10:00:25','B'
UNION ALL SELECT 2,'Hello'       ,TIMESTAMP '2022-08-01 10:02:50','A'
UNION ALL SELECT 2,'Hi'          ,TIMESTAMP '2022-08-01 10:03:50','B'
)
-- end of input, real query starts here , replace following comma with "WITH" 
,
w_match_clause AS (
  SELECT                                                                                                                                             
    *
  , event_name()
  , pattern_id()
  , match_id()
  FROM indata
  MATCH (
    PARTITION BY id ORDER BY ts
    DEFINE
      sentbya AS usr='A'
    , sentbyb AS usr='B'
    PATTERN
    p AS (sentbya sentbyb)
  )
   -- ctl SELECT * FROM w_match_clause;
   -- ctl  ID |   Message    |         ts          | Usr | event_name | pattern_id | match_id 
   -- ctl ----+--------------+---------------------+-----+------------+------------+----------
   -- ctl   1 | How are you? | 2022-08-01 10:00:05 | A   | sentbya    |          1 |        1
   -- ctl   1 | Hello there  | 2022-08-01 10:00:10 | B   | sentbyb    |          1 |        2
   -- ctl   1 | Good to know | 2022-08-01 10:00:15 | A   | sentbya    |          2 |        1
   -- ctl   1 | Bye          | 2022-08-01 10:00:25 | B   | sentbyb    |          2 |        2
   -- ctl   2 | Hello        | 2022-08-01 10:02:50 | A   | sentbya    |          1 |        1
   -- ctl   2 | Hi           | 2022-08-01 10:03:50 | B   | sentbyb    |          1 |        2
)
SELECT
  id
, MAX(ts) - MIN(ts) AS difference
FROM w_match_clause
GROUP BY
  id
, pattern_id
ORDER BY
  id;
-- out  id | difference 
-- out ----+------------
-- out   1 | 00:00:05
-- out   1 | 00:00:10
-- out   2 | 00:01

0
投票

使用 mySQL 8.0:

WITH cte AS (
    SELECT id, user, timestamp, ( LEAD(user) OVER (ORDER BY timestamp) ) AS to_user, 
        TIME_TO_SEC(TIMEDIFF(LEAD(timestamp) OVER (ORDER BY timestamp), timestamp)) AS time_diff
    FROM msg_tab
)
SELECT id, time_diff
FROM cte
WHERE user='A' AND to_user IN ('B', NULL)

0
投票

我一直在寻找类似这样的东西来做一些计算,它帮助我成功了,但我想知道如果现在我想把结果保存在一个列中,我该怎么做?

With mySQL 8.0:

使用 cte AS ( SELECT id, user, timestamp, ( LEAD(user) OVER (ORDER BY timestamp) ) AS to_user, TIME_TO_SEC(TIMEDIFF(LEAD(timestamp) OVER (ORDER BY timestamp), timestamp)) AS time_diff 来自 msg_tab ) 选择 id, time_diff 从 cte WHERE user='A' AND to_user IN ('B', NULL)

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