arrays - 连续插入遇到的三个 ID 的所有唯一组合
问题描述
我想用三个不同 ID 遇到的所有唯一组合不断更新一个表。这些 ID 可以是产品/组/区域 ID 等。我已经在这里抽象出来了。我想通过调用来更新这个表create_combinations_if_needed('{{1, 10, 100}, {2, 11, 101}}')
,这将创建组合{1, 10, 100}
,{1, 10, 100}
如果它们不存在的话。
这是我在下面做的尝试。
CREATE TABLE combinations (
id serial PRIMARY KEY,
some_id1 integer NOT NULL,
some_id2 integer NOT NULL,
some_id3 integer NOT NULL
);
CREATE UNIQUE INDEX ON combinations(some_id1, some_id2, some_id3);
CREATE OR REPLACE function create_combinations_if_needed(p_combinations integer[][]) RETURNS boolean
LANGUAGE sql AS
$$
INSERT INTO combinations (some_id1, some_id2, some_id3)
SELECT some_id1, some_id2, some_id3
FROM UNNEST(p_combinations) AS comb(some_id1, some_id3, some_id3)
ON CONFLICT (some_id1, some_id2, some_id3)
DO NOTHING
RETURNING TRUE;
$$;
但是,如果我尝试创建此函数,则会收到以下错误:
ERROR: table "comb" has 1 columns available but 3 columns specified
CONTEXT: SQL function "create_combinations_if_needed"
我究竟做错了什么?
解决方案
正如@a_horse_with_no_name 已经说明的那样: unnest() 函数不仅可以展平第一个维度,还可以展平所有嵌套元素。所以它为每个整数创建一行。这当然会导致一列(在您的情况下)有六个值。这就是异常消息的含义:您生成了一列,但预期为三列。
因此,您需要一个解决方案来仅取消嵌套第一个维度。我正在使用此处介绍的解决方案:
- https://stackoverflow.com/a/8142998/3984221来自@LukasEklund 和@ErwinBrandstetter
创建 Lukas 函数:
CREATE OR REPLACE FUNCTION unnest_2d_1d(anyarray)
RETURNS SETOF anyarray AS
$func$
SELECT array_agg($1[d1][d2])
FROM generate_subscripts($1,1) d1
, generate_subscripts($1,2) d2
GROUP BY d1
ORDER BY d1
$func$ LANGUAGE sql IMMUTABLE;
这个仅取消嵌套第一个维度。所以你可以在你的函数中使用它而不是你的 unnest() 尝试:
CREATE OR REPLACE function create_combinations_if_needed(p_combinations integer[][]) RETURNS boolean
LANGUAGE sql AS
$$
INSERT INTO combinations (some_id1, some_id2, some_id3)
SELECT unnest[1], unnest[2], unnest[3]
FROM unnest_2d_1d(p_combinations) as unnest
ON CONFLICT (some_id1, some_id2, some_id3)
DO NOTHING
RETURNING TRUE;
$$;
推荐阅读
- ios - 如何使用 1 个函数将 2 个属性保存到核心数据(Swift4)
- corda - 当音量很高时,在收集签名期间性能会变慢
- excel - 如何在 OLE2 ABAP 中对受保护的 excel 文件启用过滤器
- javascript - 如何获取每个id的数组的最小值
- node.js - 有什么方法可以自定义 LUIS 中任何话语的分数?
- kubernetes - 如何使用 kubectl 显示自己的信息?
- django - Django:存储所有应用程序通用功能的位置
- python - 在 if __ is __ 语句中使用 .lower 或 'or' 会导致 python 3.6 中的 if 语句流不正确
- rust - How to end borrow when an Option is None
- python-3.x - 尽管路径正确存在,但当我无法访问 sql 路径时,我应该看哪个方面?