首页 > 解决方案 > PostgreSQL 搜索字符串列中的子字符串列表

问题描述

我在 postreSQL 数据库中有下表(为清楚起见进行了简化):

  | serverdate |           name | value 
  |-------------------------------------
0 | 2019-12-01 | A LOC 123 DISP | 1
1 | 2019-12-01 | B LOC 456 DISP | 2
2 | 2019-12-01 | C LOC 777 DISP | 0
3 | 2019-12-01 | D LOC 000 DISP | 10
4 | 2019-12-01 | A LOC 700 DISP | 123
5 | 2019-12-01 | F LOC 777 DISP | 8

名称列是字符串类型。子串LOCDISP可以有其他不同长度的值,但在这个问题中不感兴趣。

问题:我想选择只包含某个子字符串的行。有几个子字符串,作为数组传递,格式如下:

['A_123', 'F_777'] # this is an example only

我想选择所有包含子字符串第一部分的行(用下划线'_'分隔),以及第二部分。在此示例中,使用提到的数组,我应该获得第 0 行和第 5 行(因为它们是唯一在两个部分中都完全匹配的行):

  | serverdate |           name | value 
  |-------------------------------------
0 | 2019-12-01 | A LOC 123 DISP | 1
5 | 2019-12-01 | F LOC 777 DISP | 8

第 4 行子字符串的第一部分正确,但另一部分不正确,因此不应返回。与第 2 行相同(只有第二部分匹配)。

这个查询怎么做?我对 SQL 比较陌生。

此查询是 Python 中过程的一部分,因此我可以根据需要调整输入参数(子字符串数组),但行为必须与描述的行为相同。

谢谢!

标签: sqlpostgresql

解决方案


您是否尝试过使用 regexp_replace 和子查询?

SELECT * FROM 
  (SELECT serverdate, substring(name from 1 for 1)||'_'||
          regexp_replace(name, '\D*', '', 'g') AS name, value 
  FROM t) j 
WHERE name IN('A_123', 'F_777');

或使用CTE

WITH j AS (
SELECT serverdate, substring(name from 1 for 1)||'_'||
       regexp_replace(name, '\D*', '', 'g') AS name2, 
       value,name
FROM t 
) SELECT serverdate,name,value FROM j 
  WHERE name2 IN('A_123', 'F_777');


 serverdate |      name      | value 
------------+----------------+-------
 2019-12-01 | A LOC 123 DISP |     1
 2019-12-01 | F LOC 777 DISP |     8
(2 Zeilen)

推荐阅读