我在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
名称列的类型为字符串。子字符串 LOC 和 DISP 可以具有其他长度不同的值,但此问题无关。
问题:我想选择仅包含特定子字符串的行。有几个子字符串,以ARRAY的形式传递,格式如下:
['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处理过程的一部分,因此我可以根据需要调整输入参数(子字符串数组),但是其行为必须与所描述的相同。
谢谢!
答案 0 :(得分:1)
您是否尝试过使用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)
答案 1 :(得分:1)
只需嵌套数组并使用like子句连接表
select
*
from
Table1
join
(
select
'%'||replace(unnest, '_', '%')||'%' pat
from
unnest(array['A_123', 'F_777'])
) pat_table on "name" like "pat"
只需将unnest(array['A_123', 'F_777'])
替换为unnest(string_to_array(str_variable, ','))
答案 2 :(得分:1)
感谢您的回答! Larry B的解决方案使我遇到了一个错误,但这是由外部因素引起的(我使用由我公司开发的内部工具运行查询,当使用%通配符时,它引发了错误。已经联系了支持团队),所以我无法对其进行正确的测试。
吉姆·琼斯(Jim Jones)的解决方案似乎是另一种选择,但我发现在某些情况下, name 字段中的值看起来像这样(在编写问题时没有注意到它,因为它罕见的情况):
ABC LOC 123 DISP
因此,我对解决方案进行了一些修改,以便在用''字符分割名称时抓住名称的第一部分。
(TLDR:名称的第一个子字符串可以是任意长度,但始终在开头)
我的解决方法是:
SELECT * FROM
(SELECT serverdate, split_part(name, ' ', 1)||'_'||
regexp_replace(name, '\D*', '', 'g') AS name, value
FROM t) j
WHERE name IN('A_123', 'F_777');
答案 3 :(得分:0)
split_part(name,'_',1) + '_' + split_part(name,'_',3) as name
这是查询的细分:A + _ + 123 = A_123