【问题标题】:(One table) Insert rows with Sequence(一个表)用序列插入行
【发布时间】:2019-06-04 05:26:15
【问题描述】:

这个问题是this one的延续。

我有下表egr

+---------+---------+------------+
|  egrid  |  offid  |  groupid   |
+---------+---------+------------+
|    1000 |       1 | 101        |
|    1001 |       1 | 202        |
|    1002 |       2 | 202        |
|    1003 |       2 | 404        |
+---------+---------+------------+

注意egrid 是一个序列。

我想插入 offid 2 没有的缺失 groupid(与 offid 1 相比)。结果是:

+---------+---------+------------+
|  egrid  |  offid  |  groupid   |
+---------+---------+------------+
|    1000 |       1 | 101        |
|    1001 |       1 | 202        |
|    1002 |       2 | 202        |
|    1003 |       2 | 404        |
|    1004 |       2 | 101        |   --> new row to insert
+---------+---------+------------+

我在下面的尝试,基于我的另一个问题的答案(不工作)。 我遇到的问题是序列随 select 语句递增。但是如果有 555 行 offid = 1,它将增加 555 倍,尽管最后只会插入一些。我正在寻找更好的方法。

INSERT INTO egr (egrid, offid, groupid)
  SELECT nextval('seq_egrid'), 2, groupid
    FROM egr
    WHERE offid = 1
  EXCEPT
  SELECT egrid, 2, groupid
    FROM egr
    WHERE offid = 2
ON CONFLICT DO NOTHING;

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    要仅在添加行的情况下增加 nextval,您可以尝试以下操作:

    INSERT INTO egr (egrid, offid, groupid)
      SELECT nextval('seq_egrid'), 2, g FROM (
        SELECT groupid as g
          FROM egr
          WHERE offid = 1
        EXCEPT
        SELECT groupid
          FROM egr
          WHERE offid = 2
      ) AS t
    ON CONFLICT DO NOTHING;
    

    【讨论】:

    • 不幸的是,修改架构不是一种选择。
    • @StephaneB。这样的事情有帮助吗?
    【解决方案2】:

    您可以使用以下方法生成行:

    select o.offid, g.groupid
    from (select distinct offid from egr) as o cross join
         (select groupid from egr where offid = 1) g left join
         egr
         on egr.offid = o.offid and
            egr.groupid = g.groupid
    where egr.offid is null;
    

    我不会对第一列使用序列,只使用serial 值,所以我会写:

    insert into egr (offid, groupid)
        select o.offid, g.groupid
        from (select distinct offid from egr) as o cross join
             (select groupid from egr where offid = 1) g left join
             egr
             on egr.offid = o.offid and
                egr.groupid = g.groupid
        where egr.offid is null;
    

    并让数据库分配第一个值。当然,如果你使用使用序列,你可以显式:

    insert into egr (egrid, offid, groupid)
        select nextval('seq_egrid'), o.offid, g.groupid
        from (select distinct offid from egr) as o cross join
             (select groupid from egr where offid = 1) g left join
             egr
             on egr.offid = o.offid and
                egr.groupid = g.groupid
        where egr.offid is null;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-19
      • 1970-01-01
      • 2020-03-11
      • 2014-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-30
      相关资源
      最近更新 更多