选择字符串是否仅包含子字符串一次

时间:2018-12-28 01:01:37

标签: database postgresql select count where-clause

我正在尝试创建一个报告,该报告在两个日期之间提取数据,并且在具有文本数据类型的描述列中仅出现一次字符串的地方

我已经尝试过使用“ postgresql-select-if-string-contains” stackoverflow问题中的解决方案,但它不能说明字符串在描述块中出现了多少次。

SELECT o.ownername, to_char(a.auditdate, 'MM/DD/YYYY') as dateday, 
o.additionalflags, 
o.emailaddress, o.id, a.description, a.username, 
CASE WHEN a.Action = 0 THEN 'ADD'
WHEN a.Action = 1 THEN 'EDIT'
WHEN a.Action = 2 THEN 'DELETE'
WHEN a.Action = 3 THEN 'MOVE'
WHEN a.Action = 4 THEN 'LOGIN'
WHEN a.Action = 5 THEN 'LOGOUT'
END AS Action
FROM owner o
INNER JOIN audittrail a ON o.id = a.linkid
/*
WHERE array_length(regexp_matches(description, '1\-Gets Email'), 1) = 1
*/
AND a.auditdate >= '$ASK DATE Enter the from date$' 
AND a.auditdate <= '$ASK DATE Enter the to date$'
ORDER BY o.ownername

我要筛选的列中的数据如下所示:

(ID 2) >>> LASTCHANGEDDATE: 2011-11-11 11:11:11.653868 ==> 2018-12-23 14:24:28.694724, ADDITIONALFLAGS: *1-Atest|1-Gets Email|1-Gets Snail Mail|Adopter-|donor|driver|fosterer|homechecked|homechecker|member|V-Foster Home: short-term/emergency|* ==> **1-Gets Email|1-Gets Snail Mail|Adopter-NCGSPR Dog|donor|driver|fosterer|homechecked|homechecker|member|V-Foster Home: short-term/|volunteer|,**

该列几乎是数据库中已更改内容的描述日志。斜体字是ADDITIONALFLAGS的过去,粗体字是变更后新的和当前的ADDITIONALFLAGS。我正在寻找描述行中“ 1-Gets Email”一次,因为我只关心那些已更改的消息,而不关心那些在我查询日期之前具有“ 1-Gets Email”的消息。

2 个答案:

答案 0 :(得分:0)

有些古怪,但应该可以:检查描述的长度减去搜索的文本的长度是否等于描述的长度,在该长度下,将搜索的文本替换为空字符串。

...
WHERE length(description) - length('1-Gets Email') = length(replace(description, '1-Gets Email', ''))
...

或更通用的方法:检查找到的匹配项regexp_matches()的数量,在这种情况下为1。

...
WHERE (SELECT count(*)
              FROM regexp_matches(description, '1\-Gets Email', 'g')) = 1
...

答案 1 :(得分:0)

split_part()可用于简单快速的解决方案:

...
WHERE  description ~ '1-Gets Email'
AND    split_part(description, '1-Gets Email', 3) = '';

这会将搜索模式视为定界符。如果没有第二个定界符,则没有第三部分-在这种情况下为空。
如果搜索模式可能出现在字符串的开头或结尾,我们可能会得到误报,但由于值包含在自定义分隔符中,因此您可以排除这种极端情况。

如果表很大,则可以添加一个trigram索引来支持第一个WHERE子句(description ~ 'pattern'),并使它更快。喜欢:

CREATE INDEX tbl_description_gin_trgm_idx ON tbl USING gin (description gin_trgm_ops);

请参阅: