了解为什么 rank() over 不适合不选择重复行

Mio*_*Mio 5 window-functions redshift rank

我想了解为什么我有不同的结果

我有一个名为 active_transfert 的表,用于记录图像传输

user_id | image_id | created_at
--------|----------|-----------
1       |1         |2014-07-10
1       |2         |2015-01-21
2       |1         |2015-05-23
3       |1         |2016-07-22
4       |6         |2017-06-01
4       |6         |2014-08-22
Run Code Online (Sandbox Code Playgroud)

我想为每个 image_id 返回唯一的 user_id。

SELECT user_id,
       image_id
FROM active_transfert
GROUP BY user_id,
         image_id; --50


SELECT user_id,
       image_id
FROM
  (SELECT user_id,
          image_id,
          rank() OVER (PARTITION BY user_id, image_id
                       ORDER BY created_at DESC) AS i_ranked
   FROM active_transfert) AS i
WHERE i.i_ranked = 1; -- 53
Run Code Online (Sandbox Code Playgroud)

我对 Redshift 运行这些查询。为什么我的第二个查询不能防止重复记录(相同的 user_id 和 image_id)?

预期结果 :

user_id | image_id |
--------|----------|
1       |1         |
1       |2         |
2       |1         |
3       |1         |
4       |6         |
Run Code Online (Sandbox Code Playgroud)

May*_*erg 9

RANK()是一个确定性函数,这意味着重复项将被标记为相同的等级值。您查询的输出建议,我认为有多个记录与同user_idimage_id也具有相同的created_at价值。这些记录都将返回相同的RANK()值。

如果您运行内部查询,您将看到这些重复项,其中所有三个属性都相同。如果created_date也是该组合的最大值user_id,则image_id它们的RANK()值都为 1。

要获得所需的输出,您应该使用ROW_NUMBER(). 当OVER子句中的参数不能唯一确定行时,这是一个非确定性函数,在这种情况下为真。这将为每一行分配一个唯一结果,但是当您的RANK()查询提供重复项时,它将随机为这些行中的每一行分配一个唯一值。

您的第二个查询使用ROW_NUMBER()

SELECT user_id,
       image_id
FROM
  (SELECT user_id,
          image_id,
          ROW_NUMBER() OVER (PARTITION BY user_id, image_id
                       ORDER BY created_at DESC) AS i_ranked
   FROM active_downloads) AS i
WHERE i.i_ranked = 1;
Run Code Online (Sandbox Code Playgroud)