分区时使用 PostgreSQL Case

Using PostgreSQL Case When with Partition

我正在尝试将 Case when 与分区一起使用来创建新行并标记其是否重复

我想要的输出如下所示

我正在使用的查询

我在这里找不到错误。在

之前它似乎在 SQL 服务器中工作
SELECT *,
    CASE 
        WHEN ROW_NUMBER() OVER (PARTITION BY 
            x , y > 1) THEN TRUE ELSE FALSE
    END AS is_duplicated
    FROM users
   

我猜你把括号弄错了。你能试试CASE WHEN ROW_NUMBER() OVER (PARTITION BY x , y) > 1 THEN TRUE ELSE FALSE END吗?

顺便说一下,在 Postgre 中SQL,我想你也可以这样写:

SELECT
    *,
    (ROW_NUMBER() OVER (PARTITION BY x , y) > 1) AS is_duplicated
FROM
    users

请注意,如果您想确保将正确的行标记为重复,您可能还想在 OVER 子句中包含一个 ORDER BY

顺便说一句,在 Microsoft SQL 服务器中测试此查询时,如果我在 OVER 子句中省略 ORDER BY,我会收到一条错误消息。但是,在 PostgreSQL 中没有 ORDER BY 也能正常工作。

我觉得> 1应该是这样出来的(PARTITIONBY x, y)

SELECT *,
    CASE 
        WHEN ROW_NUMBER() OVER (PARTITION BY 
            x , y) > 1 THEN TRUE ELSE FALSE
    END AS is_duplicated
    FROM users

Comprasion 运算符本身是布尔值,因此您不需要大小写:

SELECT *,
     
       ROW_NUMBER() OVER (PARTITION BY 
            x , y) > 1
     AS is_duplicated
    FROM users

但这会导致仅将第一行之后的行标记为重复,这意味着第一个 Carlo Thomas 不会重复。

因此,为了获得所需的结果,您需要:

SELECT *,
     
       (SELECT count(*) from users t WHERE t.x=u.x and t.y=u.y) > 1
     AS is_duplicated
    FROM users u;

正如其他两个答案所指出的,> 不是 partition by 的一部分。

我想首先指出,不使用 order by 使用 row_number() 是非常非常不鼓励的。如果没有 order by,每个 运行.

的结果可能不同

更重要的是,你不想row_number()。您想要 count() - 因为您想要 TRUE 所有 有重复的行上。

第二个是根本不需要case表达式,因为Postgres有布尔类型。

所以:

SELECT u.*,
       (COUNT(*) OVER (PARTITION BY x, y) > 1) AS is_duplicated
FROM users u;

Here 是一个 db<>fiddle.