【问题标题】:postgres - comparing two arrayspostgres - 比较两个数组
【发布时间】:2010-12-11 11:14:31
【问题描述】:

postgres 有一个数组数据类型,在这种情况下是一个数字数组:

CREATE TABLE sal_emp (name text, pay_by_quarter integer[]);
INSERT INTO sal_emp VALUES ('one', '{1,2,3}');
INSERT INTO sal_emp VALUES ('two', '{4,5,6}');
INSERT INTO sal_emp VALUES ('three', '{2,4,6}');
SELECT * FROM sal_emp;

Result:
one, {1,2,3}
two, {4,5,6}
three, {2,4,6}

据我所知,您只能按如下方式查询数组:

SELECT * FROM sal_emp WHERE 4=ANY(pay_by_quarter);
SELECT * FROM sal_emp WHERE ARRAY[4,5,6]=pay_by_quarter;

这意味着您可以选择包含匹配单个参数的数组的行,或者如果整个数组匹配数组参数。

我需要选择一行,其中行数组的任何成员与参数数组的任何成员匹配 - 有点像“IN”,但我不知道如何。我尝试了以下两种方法,但都不起作用:

SELECT * from sal_emp WHERE ARRAY[4,5,6]=ANY(pay_by_quarter);
SELECT * from sal_emp WHERE ANY(pay_by_quarter) IN (4,5,6);

我认为我可以通过将数组转换为字符串来做一些事情,但这听起来像是糟糕的解决方案..

有什么想法吗?

【问题讨论】:

    标签: sql arrays postgresql


    【解决方案1】:

    想通了...有一个 && 运算符

    http://www.postgresql.org/docs/current/static/functions-array.html

    "&& 重叠(有共同的元素)ARRAY[1,4,3] && ARRAY[2,1]"

    【讨论】:

      【解决方案2】:

      尽量不抄袭 pstanton 的回答,但要澄清一个用例。

      要满足具有任意值列表的两列(或多列)中的任意个条件:

       select * from mytable
       where array(col1, col2) && array('foo', 'bar', baz')
      

      【讨论】:

      • 如何在搜索的列中找到数组not中的值?
      • @thedigitalmouse 您应该将其作为一个新问题提出。
      【解决方案3】:

      要将一个数组的元素与另一个数组的元素进行至少一次匹配,您可以使用&& 运算符。仅当每个数组中至少有一个元素匹配时,它才会返回 true。

      尽管这个问题的正确答案已经存在了几十年,但为了让初学者更清楚,我添加了这个示例。

      架构:

       create table mytable (id int, value text[]);
       insert into mytable values (1,'{"dog", "cat", "fish"}');
       insert into mytable values (2,'{"elephant", "mouse"}');
       insert into mytable values (3,'{"lizard", "dog", "parrot"}');
       insert into mytable values (4,'{"bear", "bird", "cat"}');
      

      查询:

       select * from mytable where array['dog', 'cat']&&(value);
      

      输出:

      id value
      1 {dog,cat,fish}
      3 {lizard,dog,parrot}
      4 {bear,bird,cat}

      db小提琴here

      Query#2(使用通配符匹配数组元素)

      要使用通配符比较数组元素,您可以使用 unnest() 解析两个数组的每个元素并使用 Like 运算符进行比较。

         SELECT    distinct m.*
         FROM  mytable m, unnest(value)b 
         inner join  unnest(array['dog%', 'ca%']) a 
         on b LIKE a 
      

      输出:

      id value
      1 {dog,cat,fish}
      3 {lizard,dog,parrot}
      4 {bear,bird,cat}

      db小提琴here

      【讨论】:

      • 我们可以使用像select * from mytable where array['dog%', '%cat%']&&(value); 这样的通配符吗?
      • 这样不行。我为此添加了另一个答案。请检查@soung
      【解决方案4】:

      为了比较 Postgress 中的数组,有数组运算符。
      在此处找到运算符部分:https://www.postgresql.org/docs/current/functions-array.html

      比较两个数组的快速方法是这样做,

      ( (ARRAY_1 @> ARRAY_2) AND (ARRAY_1 <@ ARRAY_2) )
      

      它基本上检查 ARRAY_2 中的所有唯一值是否存在于 ARRAY_1 AND 中,反之亦然。 不要忘记同时使用检查/条件/比较(AND)

      这些称为包含运算符,它检查一个数组中的所有 唯一 值并将其与另一个进行比较。它们也被称为鸟运算符,因为运算符 @&gt; AND &lt;@ 类似于鸟的头部。

      其工作方式如下:

      ARRAY_1 <@ ARRAY_2
      // Check/Direction: Left-to-Right
      // Checks if all the unique elements in ARRAY_1 is present in ARRAY_2 as well. If yes, it will return TRUE
      // Please note this will return TRUE even if ARRAY_2 has extra elements that are not present in ARRAY_1
      

      同样,

      ARRAY_1 @> ARRAY_2
      // Note we have changed the operator to '@>' from '<@'. Check/Direction: Right-to-Left
      // Checks if all the unique elements in ARRAY_2 is present in ARRAY_1 as well. If yes, it will return TRUE
      // Please note this will return TRUE even if ARRAY_1 has extra elements that are not present in ARRAY_2
      

      所以即使元素的顺序不同,它仍然可以工作。

      查看&gt; 或&lt; 符号是避免混淆并记住这一点的简单方法。
      将带有小于号指向的 ARRAY(唯一元素)与带有大于号指向的 ARRAY(唯一元素)进行比较。
      因此,大于号指向的 ARRAY 可以包含额外的唯一元素,并且仍然返回 TRUE。

      让我们尝试一些例子

      SELECT array[1, 2, 3] @> array[1, 2, 3] AS RESULT
      !-- Returns TRUE (Check is Right-to-Left)
      
      SELECT array[1, 2, 3] @> array[3, 1, 2] AS RESULT
      !-- Returns TRUE (Check is Right-to-Left)
      
      SELECT array[1, 2, 3, 3, 3, 3] @> array[1, 2, 3] AS RESULT
      !-- Returns TRUE (Check is Right-to-Left)
      
      SELECT array[1, 2, 3, 3, 3, 3] <@ array[3, 2, 1, 3, 2, 5] AS RESULT
      !-- Returns TRUE (Check is Left-to-Right)
      
      SELECT array[1, 2, 3, 4] <@ array[1, 2, 3] AS RESULT
      !-- Returns FALSE (Check is Left-to-Right)
      
      SELECT array[1, 2, 3, 4] @> array[1, 2, 3] AS RESULT
      !-- Returns TRUE (Check is Right-to-Left)
      
      SELECT array[1, 2, 3] <@ null AS RESULT
      !-- Returns empty (Check is Left-to-Right)
      
      SELECT array[1, 2, 3] @> null AS RESULT
      !-- Returns empty (Check is Right-to-Left)
      
      SELECT null <@ null AS RESULT
      !-- Doesn't work if both the values are null - Error: Operator is not unique: unknown <@ unknown
      
      SELECT array[1, 2, 3] <@ array[] AS RESULT
      !-- Doesn't work on empty arrays - Error: Cannot determine type of empty array
      
      SELECT array[] <@ array[] AS RESULT
      !-- Doesn't work on empty arrays - Error: Cannot determine type of empty array
      

      请注意

      • 这用于比较数组。
      • 工作原理是从两个数组中提取唯一值 - 然后比较它们。
      • 它不检查 ARRAY 中的元素计数。即,即使两个数组的长度不同,它也可以返回 TRUE([1, 2] @&gt; [1] 或 [1, 1] @&gt; [1] 仍然是 TRUE)
      • 如果两个值都是NULL,则不起作用
      • 如果任一数组为空则不起作用 ([])

      【讨论】:

        猜你喜欢
        • 2017-10-29
        • 1970-01-01
        • 1970-01-01
        • 2012-12-26
        • 2021-03-21
        • 2019-02-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多