【问题标题】:Why Postgresql doesn't allow grouping sets in INSERT SELECT queries?为什么 Postgresql 不允许在 INSERT SELECT 查询中进行分组?
【发布时间】:2017-09-14 22:22:35
【问题描述】:

这里的问题很简单,Postgresql 不允许以下查询结构:

-- TABLE OF FACTS
CREATE TABLE facts_table (
    id integer NOT NULL,
    description CHARACTER VARYING(50),
    amount NUMERIC(12,2) DEFAULT 0,
    quantity INTEGER,
    detail_1 CHARACTER VARYING(50),
    detail_2 CHARACTER VARYING(50),
    detail_3 CHARACTER VARYING(50),
    time TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT LOCALTIMESTAMP(0)
);
ALTER TABLE facts_table ADD PRIMARY KEY(id);

-- SUMMARIZED TABLE
CREATE TABLE table_cube (
    id INTEGER,
    description CHARACTER VARYING(50),
    amount NUMERIC(12,2) DEFAULT 0,
    quantity INTEGER,
    time TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT LOCALTIMESTAMP(0)
);
ALTER TABLE table_cube ADD PRIMARY KEY(id);

INSERT INTO table_cube(id, description, amount, quantity, time)
    SELECT
        id,
        description,
        SUM(amount) AS amount,
        SUM(quantity) AS quantity,
        time
    FROM facts_table
    GROUP BY CUBE(id, description, time);
----------------------------------------------------------------
ERROR: grouping sets are not allowed in INSERT SELECT queries.

我认为很明显CUBE 在指示为分组集的每个字段上产生null 结果(因为它计算每个可能的组合),因此我不能在我的table_cube 表中插入该行,所以, Postgres 是否只是假设我正在尝试在带有 PK 字段的表中插入一行?即使table_cube表没有PK,也无法做到。

谢谢。

版本:PostgreSQL 9.6

【问题讨论】:

  • 这(半)有趣。我不知道 Postgres 有这个限制。
  • 在删除 table_cube 上的主键后在这里工作正常,这使得 table_cube.id NOT NULL,我找不到类似“在 INSERT SELECT 查询中不允许分组集”之类的东西。来源。您实际上是在使用 Postgres 还是这是一些奇怪的分叉/扩展?
  • 刚刚在 postgres 9.6 上使用一些虚拟数据测试了上述脚本。删除主键约束后工作正常。如果需要约束,请对所有分组集列使用唯一索引:CREATE UNIQUE INDEX unq_table_cube_id_description_time ON table_cube(id, description, time); 请使用有关数据库和版本的更多信息更新您的问题
  • 不知道,但我希望您可以通过将分组集查询包装在 CTE 或 INSERT INTO ... SELECT ... FROM (SELECT ...) 中来解决它
  • 抱歉回复晚了。 Haleema Ali 您使用UNIQUE INDEX 提出的解决方案确实有效。如果您愿意,请随时发布问题的答案。

标签: sql postgresql


【解决方案1】:

您已将 table_cube(id) 定义为主键。所以,如果 Cube 包含 null 值,不能插入。我已经检查了没有 id 作为 Primary 键,它工作正常,当将 id 定义为主键时出现错误:

"ERROR:id contains null values"  SQL state: 23502   

根据 Haleemur Ali 的建议,

  "If a constraint is required, use a unique index with all the grouping 
  set columns: CREATE UNIQUE INDEX unq_table_cube_id_description_time ON 
  table_cube(id, description, time); Please update your question with more 
  information on database & version."

是一个不错的选择。但是您必须删除“Id”上的主键并按照上面的建议仅分配唯一键,因为主键和唯一键再次出现此错误:

   ERROR:  null value in column "id" violates not-null constraint
   DETAIL:  Failing row contains (null, null, 1300, 1522, null).
   SQL state: 23502

所以,结论是,唯一索引不需要主键,或者多维数据集不需要唯一索引或主键。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-02
    • 1970-01-01
    • 1970-01-01
    • 2014-02-06
    • 1970-01-01
    • 2019-05-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多