SQL查询点仅在超过特定时间时更改

时间:2017-08-03 05:58:11

标签: sql database postgresql

假设我有一张格式为

的表格
user, fav_colour, date

包含样本数据:

a, green, 2015-10-1
a, green, 2016-10-1
a, yellow, 2016-12-1
b, red, 2015-10-1
b, red, 2016-10-1
b, red, 2017-10-1
c, black, 2014-10-1
c, black, 2015-10-1
c, blue, 2016-02-1

如何运行返回用户的查询,其中最新fav_colour与之前的fav_colour不同,时差至少为3个月

所以查询将返回

c

a不包括在内,因为黄色仅在两个月后跟随绿色

3 个答案:

答案 0 :(得分:1)

以下查询使用的方法是首先将表格限制为每个用户的两个最新记录,然后检查最近和最近日期之间的月份差异。

SELECT
    t.user
FROM
(
    SELECT t.*,
        ROW_NUMBER() OVER (PARTITION BY t.user ORDER BY t.date DESC) rn
    FROM your_table t
) t
WHERE t.rn <= 2
GROUP BY t.user
HAVING
    MAX(t.fav_colour) <> MIN(t.fav_colour) AND   -- different colors
    AGE(MAX(t.date::date), MIN(t.date::date)) >= INTERVAL '3 MONTHS';
   -- above date calculation ensures 3 months or greater apart

在这里演示:

Rextester

答案 1 :(得分:1)

您可以使用lag窗口函数查找每一行的上一行。但请注意,您不能在where子句中使用它,因此您必须使用子查询或类似的东西:

SELECT username
FROM   (SELECT username,
               fav_colour,
               LAG(fav_colour) OVER (PARTITION BY username ORDER BY date) AS
                  prev_fav_colour,
               date,
               LAG(date) OVER (PARTITION BY username ORDER BY date) AS
                   prev_date
        FROM   colours) c
WHERE  fav_colour != prev_fav_colour AND
       AGE(date, prev_date) >= INTERVAL '3 MONTHS';

答案 2 :(得分:1)

与我不同的方法,但希望给出相同的答案。

1)我已经制作了一个公用表表达式(CTE),它添加一个行号,按日期升序对每个用户fav_colour进行排序。

2)然后我自己加入了用户和row_number +1上的CTE,因此每条记录应与该用户的下一条记录匹配。

3)然后在WHERE子句中我有3个月的标准和不同的颜色

希望这有帮助!

WITH CTE
AS
(
SELECT 
user, 
fav_colour, 
date,
ROW_NUMBER() OVER (PARTITION BY user ORDER BY date ASC) as rn
)

SELECT 
CTE1.user
FROM CTE AS CTE1
INNER JOIN CTE AS CTE2 CTE1.user=CTE2.user ON CTE1.rn=(CTE2.rn+1)
WHERE DATEDIFF(mm,CTE1.date,CTE2.date) >=3
AND CTE1.fav_colour<>CTE2.fav_colour;