【问题标题】:Using PostgreSQL Case When with Partition分区时使用 PostgreSQL 案例
【发布时间】:2021-08-10 09:33:21
【问题描述】:

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

我想要的输出如下所示

我正在使用的查询

我在这里找不到错误。它似乎以前在 SQL Server 中工作过

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

【问题讨论】:

  • 根据问题指南,请不要发布代码、数据、错误消息等的图像 - 将文本复制或键入问题中。请保留将图像用于图表或演示渲染错误,无法通过文本准确描述的事情。
  • 你已经标记了 SQL Server,但在你的标题中提到了 PostgreSQL——它是什么?
  • @DaleK 。 . .根据使用TRUEFALSE 作为布尔值的查询,我猜它应该是PostgreSQL。

标签: sql postgresql case window-functions


【解决方案1】:

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

顺便说一句,在 PostgreSQL 中,我想你也可以这样写:

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

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

顺便说一句,在 Microsoft SQL Server 中测试此查询时,如果我在 OVER 子句中省略了 ORDER BY,则会收到一条错误消息。但是,在 PostgreSQL 中没有 ORDER BY 时它确实可以正常工作。

【讨论】:

    【解决方案2】:

    我认为> 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
    

    比较运算符本身的结果是布尔值,所以你不需要大小写:

    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;
    

    【讨论】:

    • 也许 OP 的目的是将除第一个重复项之外的所有重复项标记为重复项。我无法透露任何信息,所以我只需要假设 OP 知道他们在做什么。但是,为了确定组/分区中正确的第一行,我还希望在OVER 部分中有一个ORDER BY(可能基于主键值),以便将正确的记录检测为第一行。
    • @BartHofland 是的,问题有点不清楚。这就是为什么我给出了两个答案,一个是他的查询的小修复,第二个是所需的输出。
    【解决方案3】:

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

    我想首先指出的是,使用 row_number() 而不使用 order by 是非常非常不鼓励的。如果没有 order by,每次运行的结果可能不同。

    更重要的是,你不想要row_number()。你想要count()——因为你想要TRUE出现在所有行有重复的地方。

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

    所以:

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

    Here 是一个 dbfiddle。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多