代码之家  ›  专栏  ›  技术社区  ›  Souvik Ray

如何对包含带命令分隔值的字符串的列值执行搜索查询?

  •  1
  • Souvik Ray  · 技术社区  · 6 年前

    我有一张如下所示的桌子

        date    |                            tags   |   name               
    ------------+-----------------------------------+--------         
     2018-10-08 | 100.21.100.1, cpu, del               ZONE1
     2018-10-08 | 100.21.100.1, mem, blr              ZONE2
     2018-10-08 | 110.22.100.3, cpu, blr               ZONE3
     2018-10-09 | 110.22.100.3, down, hyd              ZONE2
     2018-10-09 | 110.22.100.3, down, del              ZONE1
    

    name 对于在 tags

    此处列 标签

    例如,我有一个字符串列表 ["down", "110.22.100.3"] . 现在,如果我查找包含列表中的字符串的表,我应该得到最后两行的名称 ZONE2, ZONE1 分别。

    现在我知道有一种东西叫做 in 但我不太清楚这里怎么用。

    我试过下面这样的方法

    select name from zone_table where 'down, 110.22.100.3' in tags;
    

    但我有语法错误。我该怎么做?

    3 回复  |  直到 5 年前
        1
  •  1
  •   Vishal Raghavan    6 年前

    select name from zone_table where 
    string_to_array(replace(tags,' ',''),',')@>
    string_to_array(replace('down, 110.22.100.3',' ',''),',');
    

    1) 使用replace删除现有字符串中的空格,以便正确分隔字符串\u到\u数组,前面没有空格

    string_to_array 将字符串转换为以逗号分隔的数组。

    3) @> contains 操作人员

    如果你想整体匹配

    select name from zone_table where POSITION('down, 110.22.100.3' in tags)!=0
    

    对于单独的比赛你可以做

    select name from zone_table where POSITION('down' in tags)!=0 and 
    POSITION('110.22.100.3' in tags)!=0
    

    关于职位的更多信息 here

        2
  •  1
  •   Tim Biegeleisen    6 年前

    我们可以试着用 LIKE 运算符,并检查CSV标记列表中是否存在每个标记:

    SELECT name
    FROM zone_table
    WHERE ', ' || tags LIKE '%, down,%' AND ', ' || tags LIKE '%, 110.22.100.3,%';
    

    enter image description here

    Demo

        3
  •  1
  •   S-Man    6 年前

    demo: db<>fiddle

    我会用数组重叠做一个检查( && 操作员):

    SELECT name 
    FROM zone_table 
    WHERE string_to_array('down, 110.22.100.3', ',') && string_to_array(tags,',')
    
    1. 拆分字符串列表(列值和比较文本 'down, 110.22.100.3' )使用 string_to_array() (当然,如果比较文本已经是数组,则不必拆分它)
    2. 现在 && 操作符检查两个数组是否重叠:它检查一个数组元素是否是两个数组的一部分( documentation


    注意:
    1. “日期”是Postgres中的保留字。我建议重命名此列。
    2. 在您的示例中,字符串列表的分隔符是 ", " 而不是 "," ", " "," 这使得一些事情变得更容易(撇开@TimBiegeleisen关于将值存储为字符串列表的完全一致的想法不谈)