WITH DELETE Redshift语法错误

时间:2017-07-21 01:11:41

标签: sql amazon-redshift greatest-n-per-group

以下代码适用于SELECT语句:

WITH 
  smaller_uuid AS (
    SELECT
      id, uuid, email, first_name, last_name, display_name
    FROM stack_users_production.users AS user1
    WHERE EXISTS (
      SELECT
        id, uuid, email
      FROM
        stack_users_production.users AS user2
      WHERE
        user1.id = user2.id AND
        user1.email = user2.email AND
        user1.uuid < user2.uuid
    )
  )

SELECT 
  id, uuid, email, first_name, last_name, display_name
FROM 
  stack_users_production.users
WHERE
  uuid IN (SELECT uuid FROM smaller_uuid);

但是下面的代码不适用于DELETE语句:

WITH 
  smaller_uuid AS (
    SELECT
      id, uuid, email, first_name, last_name, display_name
    FROM stack_users_production.users AS user1
     WHERE EXISTS (
      SELECT
        id, uuid, email
      FROM
        stack_users_production.users AS user2
      WHERE
        user1.id = user2.id AND
        user1.email = user2.email AND
        user1.uuid < user2.uuid
    )
  )

DELETE FROM 
  stack_users_production.users
WHERE
  uuid IN (SELECT uuid FROM smaller_uuid);

它说语法错误:

psql:snippets.pgsql:113: ERROR:  syntax error at or near "DELETE"
LINE 18: DELETE FROM

我正在使用PostgreSQL 9.6.3,并在执行此查询时连接到AWS Redshift。

1 个答案:

答案 0 :(得分:5)

Redshift不是PostgreSQL ,它是基于(古代!)Postgres 8.0的分支,并且自此开始单独开发。这是一个误解:

  

我正在使用PostgreSQL 9.6.3,并在执行此查询时连接到AWS Redshift。

您正在使用 psql (Postgres命令行界面),从错误消息中可以清楚地看到这一点。但是你正在访问一个Redshift数据库,这意味着你根本就没有使用PostgreSQL 9.6.3。

我编辑了你的问题以澄清。

Unsupported PostgreSQL Features的列表很长 - 不完整。除其他外,不支持data-modifying CTEs - 或写操作中的任何CTE。在此页面上记录:Features That Are Implemented Differently

  

INSERT,UPDATE和DELETE
  不支持WITH。

这就是SELECT有效的原因,但DELETE没有。

在此期间,Amazon also warns

  

仅支持8.x版本的PostgreSQL查询工具psql。

使用Postgres 9.6附带的psql可能会增加混乱。

您的查询在PostgreSQL中可以正常工作 - 即使您可以从根本上简化:

DELETE FROM stack_users_production.users u
WHERE  EXISTS (
   SELECT 1
   FROM   stack_users_production.users
   WHERE  id    = u.id
   AND    email = u.email
   AND    uuid  > u.uuid
   );

这也可能适用于Redshift。

但是,请注意,此DELETE不一定会(id, email)唯一。可能有多个行具有相同的uuid - 除非您知道不可能发生。否则,您需要一个带有DISTINCT ONrow_number()的子查询(也在Redshift中实现),以保证单个行具有每个{{1}的“最大”uuid作为幸存者。