【问题标题】:Update composite type inside array更新数组内的复合类型
【发布时间】:2016-08-01 19:11:50
【问题描述】:

有没有一种简单的方法来更新数组中的复合类型?

目前我有下表(我截断了其他字段):

CREATE TYPE order_item AS (delivery_date DATE, status INT);
CREATE TABLE demo (id SERIAL PRIMARY KEY, data order_item[]);

我想更新所有order_items 中的status。当大于1时,所有status都应该更新+ 1

对于没有数组字段的表,这很容易:

UPDATE mytab SET complex_col.r = (complex_col).r + 1;

但是,我想在一个数组做同样的事情。

【问题讨论】:

    标签: sql arrays postgresql sql-update unnest


    【解决方案1】:

    问题的根源在于关系设计。规范化的模式(1:n 关系中的单独表)将比数组列更干净,并且更容易索引或更新等。也几乎不会占用更多磁盘空间,数组开销类似于行开销。

    虽然坚持您不幸的设计,但您必须取消嵌套数组,更新并聚合回来,注意不要在每一步都破坏:

    我想更新所有order_items 中的status。当大于1时,所有status都应该更新+ 1

    UPDATE demo d
    SET    data = x.data
    FROM (
       SELECT d.id, array_agg((o.delivery_date
                             , CASE WHEN o.status > 1 THEN o.status + 1 ELSE o.status END
                               )::order_item) AS data
       FROM   demo d
       LEFT   JOIN  LATERAL unnest(data) o ON true
       GROUP  BY d.id
       HAVING count(*) FILTER (WHERE o.status > 1) > 0
       ) x
    WHERE  d.id = x.id;
    

    元素的顺序可能不会改变,但没有ORDER BY就无法保证。
    为了保证元素的原始顺序:

    【讨论】:

    • 实际上表要大得多,我只需要更新迁移引起的状态。 :(
    • @ChristianSchmitt:考虑添加的关于元素顺序的注释。
    猜你喜欢
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    • 2022-10-14
    • 1970-01-01
    • 1970-01-01
    • 2017-01-25
    • 1970-01-01
    • 2015-01-23
    相关资源
    最近更新 更多