将数组与Postgres中的数组列进行比较

时间:2018-11-05 17:53:36

标签: postgresql activerecord rails-activerecord

#  things               :string           is an Array

scope :things, ->(q) { where('ARRAY[?]::varchar[] IN things', Array.wrap(q)) }

scope :things, ->(q) { where('things && ARRAY[?]::varchar[]', Array.wrap(q)) }

scope :things, ->(q) { where('ARRAY[?]::varchar[] <@ things', Array.wrap(q)) }

我尝试了一些版本,但似乎找不到合适的咒语。我正在寻找数组中具有任何内容的任何行...是否存在任何重叠?

[1, 2, 3] & [1, 8] = t
[1, 2, 3] & [8, 9] = f

我正在尝试模仿ActiveRecord的默认where行为。如果我给它一个数组,它将得到所有匹配的行。 postgres数组有可能吗?效率高吗?

1 个答案:

答案 0 :(得分:1)

执行此操作的一种方法是将数组转换为一组行。将数组设置为行集之后,可以在它们之间进行交集并检查结果是否为空集。

例如:

CREATE TABLE my_test_table(id BIGINT, test_array BIGINT[]);
INSERT INTO my_test_table(id, test_array)
  VALUES
  (1, array[1,2,3]),
    (2, ARRAY[1,5,8]);

SELECT * FROM my_test_table
 WHERE  array_length((SELECT array
    (
        SELECT UNNEST(test_array)
        INTERSECT
        SELECT UNNEST(array[3,15,2])
    )), 1) > 0;

上面SELECT语句的结果是:

1 | {1,2,3}

这允许对2个数组的元素进行更复杂的匹配。例如,如果您想选择具有至少2个公共元素的数组,则只需将WHERE部分更改为

 WHERE  array_length((SELECT array
    (
        SELECT UNNEST(test_array)
        INTERSECT
        SELECT UNNEST(array[3,15,2])
    )), 1) > 1;