如何 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
我们可以使用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
我有一个 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
我们可以使用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