如何 select SQL 中的第 n 个实例计数?

how to select the nth instance in a SQL count?

我有一个 table,其中每一行都有一个用户 ID 和他们开始一个级别的时间戳。

user    timestamp
1   2018-11-04
1   2018-11-07
1   2018-11-09
1   2018-11-09
2   2019-11-02
2   2019-11-03
2   2019-11-06
3   2019-11-10
3   2019-11-13
3   2019-11-15

我需要 select 用户第二次启动关卡的时间戳。我试过:`

select distinct user, timestamp 
from table,
  (select user, count(*) 
   from table
    group by 1
    having count(outcome) > 1) tbl
where table.user = tbl.user and count(*) = 2 

预期结果:

user    timestamp
1   2018-11-07
2   2019-11-03
3   2019-11-13

如有任何帮助,我们将不胜感激! (如果格式不对,我深表歉意,这是我的第一个问题。

如果您使用的 DBMS 支持 CTE 和 window 函数,您可以使用 ROW_NUMBER() 和 select 第二行每个 user:

WITH CTE AS (
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY user ORDER BY timestamp) AS rn
    FROM times
)
SELECT user, timestamp
FROM CTE
WHERE rn = 2

请注意,您实际上并不需要 CTE,您可以将 CTE 编写为子查询:

SELECT user, timestamp
FROM (
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY user ORDER BY timestamp) AS rn
    FROM times
) t
WHERE rn = 2

输出

user    timestamp
1       2018-11-07
2       2019-11-03
3       2019-11-13

MySQL 8 demo on dbfiddle

我们可以使用dense_rank设置排名,然后使用嵌套查询获取排名为2(当用户第二次访问系统时)的userId。

SELECT USERID,TIMESTAMP
    FROM (
        SELECT *
            ,ROW_NUMBER() OVER (
                PARTITION BY USERID ORDER BY TIMESTAMP
                ) AS STAMPRANK
        FROM DEMOTABLE
        ) T
    WHERE T.STAMPRANK = 2

您不需要为此使用子查询,因为 Snowflake 支持 QUALIFY

这个功能我觉得除了Snowflake只有Teradata才有,为什么我不是很明白,非常方便。来自文档:In a SELECT statement, the QUALIFY clause filters the results of window functions。因此,将 ROW_NUMBER() 与按 TimeStamp 排序的 User 上的分区一起使用,以动态创建和过滤订购号。

SELECT * FROM TABLE
QUALIFY ROW_NUMBER() OVER(PARTITION BY user ORDER BY timestamp) = 2;

结果:

USER    TIMESTAMP
3       2019-11-13
2       2019-11-03
1       2018-11-07