简体   繁体   English

postgresql中组内操作之间的时间间隔

[英]Time interval between actions within a group in postgresql

I have a table with users, risk level, and timestamp of that risk.我有一张表,其中包含用户、风险级别和该风险的时间戳。 It looks like this:它看起来像这样:

user用户 risk风险 timestamp时间戳
Jim吉姆 high高的 2022-01-01 2022-01-01
Jim吉姆 low低的 2022-01-02 2022-01-02
Bob鲍勃 low低的 2022-01-03 2022-01-03
Bob鲍勃 high高的 2022-01-05 2022-01-05
Bob鲍勃 low低的 2022-01-07 2022-01-07
Kev凯夫 high高的 2022-01-08 2022-01-08
Kev凯夫 low低的 2022-01-10 2022-01-10
Kev凯夫 high高的 2022-01-15 2022-01-15
Kev凯夫 low低的 2022-01-23 2022-01-23

I want to find how long it takes for a user to go from high risk to low , so it would look something like this:我想知道用户从high risk 到low需要多长时间,所以它看起来像这样:

user用户 high_timestamp高时间戳 low_timestamp低时间戳 duration期间
Jim吉姆 2022-01-01 2022-01-01 2022-01-02 2022-01-02 1 day 1天
Bob鲍勃 2022-01-05 2022-01-05 2022-01-07 2022-01-07 2 day 2天
Kev凯夫 2022-01-08 2022-01-08 2022-01-10 2022-01-10 2 day 2天
Kev凯夫 2022-01-15 2022-01-15 2022-01-23 2022-01-23 8 day 8天

You could accomplish this with window functions and FILTER , but the way with the least code would be to do something like:您可以使用窗口函数和FILTER来完成此操作,但使用最少代码的方法是执行以下操作:

SELECT
    "user",
    timestamp AS high_timestamp,
    (SELECT timestamp AS prior_high_timestamp
     FROM t highs
     WHERE highs."user"=t.user AND highs.event='high' AND highs.time<t.time
     ORDER BY time DESC LIMIT 1)
FROM t
WHERE risk='low';

If performance is a concern I might test different options, however.但是,如果性能是一个问题,我可能会测试不同的选项。

You can use LEFT JOIN LATERAL to get user rows with high value in risk column not followed by low value at all.您可以使用LEFT JOIN LATERAL来获取risk列中具有high值的用户行,而不是low It would be like:就像:

SELECT 
   high."user",
   high.timestamp as high_timestamp, 
   low.timestamp as low_timestamp,
   CAST(low.timestamp - high.timestamp AS TEXT) || ' day' as duration
FROM user_risk high
LEFT JOIN LATERAL (
    SELECT
        "user", 
        timestamp
    FROM user_risk 
    WHERE risk = 'low' AND "user" = high."user" AND timestamp >= high.timestamp
    ORDER BY timestamp
    LIMIT 1
) low ON TRUE
WHERE risk = 'high'

Please, check working demo at https://www.db-fiddle.com/f/gRhrkRrvLfBvYGXFAVU7Vc/1 .请在https://www.db-fiddle.com/f/gRhrkRrvLfBvYGXFAVU7Vc/1查看工作演示。

I've added one more row at the end ('Kev', 'high', '2022-01-25') , that is not followed by low risk value to demonstrate the case我在最后添加了一行('Kev', 'high', '2022-01-25') ,后面没有low风险值来演示案例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM