【问题标题】:SQL - RANK() with multiple WHERE and GROUP BYSQL - RANK() 与多个 WHERE 和 GROUP BY
【发布时间】:2020-07-08 20:57:49
【问题描述】:

我有一张带有 userid 和 date_accessed 的表。 (每个用户标识有多个日期,但每个用户标识的日期数量不同。)

数据如下:

userid | date_accessed
A.     | 2019-01-01
B.     | 2019-01-02
A.     | 2019-01-03
A.     | 2019-01-04
B.     | 2019-01-04

数据库中还有很多其他列,但我没有使用它们,但基本上每个用户执行操作的每一天都有一行。

我想对表进行排序,使其按用户 ID 分区,每个用户 ID 的 date_accessed 按时间顺序排列。

userid | date_accessed | rank
A.     | 2019-01-01   | 1
A.     | 2019-01-03    | 2
A.     | 2019-01-04   | 3
B.     | 2019-01-02   | 1
B.     | 2019-01-04   | 2

我的查询是:

WITH a AS (
  SELECT
    userid
  FROM table_1
  WHERE 
    date_accessed <= '2019-01-01'
    AND date_accessed >= '2019-01-10'
  HAVING
    COUNT(DISTINCT date_accessed) > 1
)

SELECT
    userid,
    date_accessed,
    RANK() OVER (
      PARTITION BY userid
      ORDER BY date_accessed ASC)
FROM table_1
WHERE
    userid IN (SELECT * FROM a)
    AND date_accessed <= '2019-01-01'
    AND date_accessed >= '2019-01-10'
GROUP BY userid, date_accessed

日期范围(date_1 和 date_2)涵盖 10 天。相反,我的查询只是列出/排列每个用户 ID 的所有 10 天,即使并非所有用户 ID 都应该有每个这些日期的相应条目。即它看起来像这样:

userid | date_accessed | rank
A.     | 2019-01-01   | 1
A.     | 2019-01-02   | 2
A.     | 2019-01-03   | 3
A.     | 2019-01-04   | 4
A.     | 2019-01-05   | 5
...
A.     | 2019-01-10   | 10
B.     | 2019-01-01   | 1
B.     | 2019-01-02   | 2

等等。

我认为问题可能出在我的 GROUP BY 上,但如果没有 GROUP BY,查询就无法运行——我是否需要以某种方式嵌套我的 RANK()?

我做错了什么?

【问题讨论】:

  • 你能提供样本数据和想要的结果吗?
  • 嗨,戈登,刚刚更新了我的帖子!这有帮助吗?
  • “没有 GROUP BY,查询无法运行”到底是什么意思?是否有错误消息或意外结果?
  • 每个用户和日期是否超过 1 行?
  • @spencer7593,对不起——我在上面的日期格式错误,但在我的实际查询/实际数据库中是正确的。我会更正我的帖子以避免混淆

标签: mysql sql presto rank partition


【解决方案1】:

您是否尝试过 ROW_NUMBER 而不是 RANK? GROUP BY 的目的是什么?

试试这个:

;WITH a as
(SELECT 
   userid,
   date_accessed,
   ROW_NUMBER() OVER ( PARTITION BY userid ORDER BY date_accessed ASC) AS rnk
FROM table
WHERE 
   userid IN ( SELECT * FROM other_table )
   AND date_accessed <= 'date_1'
   AND date_accessed >= 'date_2'
)
SELECT userid, date_accessed, rnk
from a
GROUP BY userid, date_accessed

【讨论】:

    【解决方案2】:

    使用 CTE 为每个 user_iddate_accessed 返回不同的行,过滤出您想要的日期,然后使用 ROW_NUMBER() 获得排名:

    WITH cte AS (
      SELECT DISTINCT userid, date_accessed
      FROM table_1
      WHERE date_accessed >= '2019-01-01' AND date_accessed <= '2019-01-10'
    )
    SELECT userid, date_accessed,
        ROW_NUMBER() OVER (PARTITION BY userid ORDER BY date_accessed ASC) `rank`
    FROM cte
    

    查看简化的demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-31
      • 2022-06-14
      • 2021-12-31
      • 1970-01-01
      相关资源
      最近更新 更多