我正在尝试创建一个报告,该报告在两个日期之间提取数据,并且在具有文本数据类型的描述列中仅出现一次字符串的地方
我已经尝试过使用“ 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”的消息。
答案 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);
请参阅: