【问题标题】:Postgres: Select multiple columns and compare with arrayPostgres:选择多列并与数组进行比较
【发布时间】:2025-12-27 10:05:11
【问题描述】:

我想在 Postgres 12 数据库中的一个 PL/PGSQL 函数中执行以下操作(用某种简化的伪代码编写):

SELECT numcolA, numcolB FROM myitemtable INTO _unused_items_array;

FOR EACH _numcol1, _numcol2 IN SELECT num_col1, num_col2 FROM some_items_table LOOP

    IF CONTAINS(_unused_items_array, [_numcol1, _numcol2]) THEN
        REMOVE_ARRAY_ITEM_IF_EXISTS(_unused_items_array, [_numcol1, _numcol2]);
        -- following lines containing REMOVE_ARRAY_ITEM_IF_EXISTS are simplified
        -- they will be in real life much more difficult to calculate
        REMOVE_ARRAY_ITEM_IF_EXISTS(_unused_items_array, [_numcol1 - 1, _numcol2 - 1]);
        REMOVE_ARRAY_ITEM_IF_EXISTS(_unused_items_array, [_numcol1 + 3, _numcol2 + 3]);
    END IF;

END LOOP

SELECT numcolA, numcolB FROM myitemtable INTO _used_items_array;
FOR EACH _unused_item IN _unused_items_array
    REMOVE_ARRAY_ITEM_IF_EXISTS(_used_items_array, _unused_item);

不能只用 SQL 来完成,因为计算(上面的注释)比这里写的要复杂得多。

那么,有没有人知道我如何用 PL/PGSQL 来解决它——因为 PL/PGSQL 中的数组函数让我在解决这个问题时发疯了(在 C# 中它会在一秒钟内完成——但没有选择) .

添加(编辑) 根据要求,我添加了一些示例数据来解释要求:

myitemtable 包含(除其他外)以下列:

+ -------------- + -------------- +
| numcolA        | numcolB        |
+ -------------- + -------------- +
| 1              | 1              |
+ -------------- + -------------- +
| 1              | 2              |
+ -------------- + -------------- +
| 2              | 5              |
+ -------------- + -------------- +
| 2              | 9              |
+ -------------- + -------------- +

some_items_table 包含(除其他外)以下列:

+ -------------- + -------------- +
| num_col1       | num_col2       |
+ -------------- + -------------- +
| 1              | 2              |
+ -------------- + -------------- +
| 2              | 9              |
+ -------------- + -------------- +

在 if 条件下,会有一些其他项目“虚拟计算”,比如说(1|1), (1|3), (2|2), (2|8), (2|10), (3|9),它将检查这些项目是否在 _unused_items_array 中(如果它们是则将被删除 - 有些是,你可以见)。

这一切都将在最后导致一个 _used_items_array 在这个例子中将只包含项目(2|5)

【问题讨论】:

  • 通常不使用数组是有问题的数据库设计的标志。正确归一化的模型通常不需要这个。也许如果您退后一步,向我们解释您要解决的潜在问题(通过提供示例数据和预期结果),我们可以提出不需要使用数组开头的集合基础、关系解决方案
  • [_numcol1 + 3, _numcol2 + 3] 是表示数组中要删除的元素的索引还是要删除的?数组元素是什么数据类型?
  • 感谢您的回复。我理解您对数据库设计的评论,但请确保:这里不是这种情况。 REMOVE_ARRAY_ITEM_IF_EXISTS 的要求是该元素将被移除。
  • 我已经编辑了问题的描述,并(按要求)添加了一些示例数据和预期结果。
  • 那么你有答案了吗?

标签: sql postgresql plpgsql


【解决方案1】:

许多方法可以做到这一点,简单的 SQL DELETE 可能是“最简单的”:

DELETE FROM myitemtable m
USING  some_items_table s
WHERE (m.numcolA , m.numcolB) IN (
      (s.num_col1, s.num_col2)  -- row values from some_items_table
    , (1,1), (1,3), (2,2), (2,8), (2,10), (3,9) -- "virtually calculated" row values
      );

db小提琴here

这是比较 ROW 值。不要忘记在这样的测试中 NULL 值不会比较相等。相关:

如果需要,您可以将语句嵌套在 PL/pgSQL 函数中。

似乎没有必要涉及数组。 XY problem?不过,使用数组也很简单。

【讨论】:

  • 请允许我,为什么 (2,5) 被删除了?好像我投票给你的答案,你不能增加分数。我想我投了太多你的答案。
  • @Mark (2,5) 是示例中唯一的 幸存 行。关于声誉见:meta.stackexchange.com/a/7238/169168
  • 对不起。阅读太多你的好答案......我想现在脑子很痛。
最近更新 更多