[英]Find occurrence of string using generate_series
Query:询问:
select id , DATASTRING from mixdatatable
Output:输出:
id DATASTRING
1 131A131A- - <> <<<><<>< afa A A ...
2 2323354A12<><>A .....HELLO <> A
Now I want to find all occurrences of 'A' in the column datastring.现在我想在列数据字符串中找到所有出现的 'A'。
I tried the below query, which gives output correct for hard coded string but how can I use below query with table 'mixdatatable'.我尝试了下面的查询,它为硬编码字符串提供了正确的输出,但是如何将下面的查询与表“mixdatatable”一起使用。
select *
from (
select case
when (string_to_array(trim(trailing '.' from regexp_replace('131A131A- - <> <<<><<>< afa A A ...','(.)','\\1.','g')),'.'))[i]='A'
then i
end as Position
from generate_series(1,length('131A131A- - <> <<<><<>< afa A A ...')) i
) foo
where count is not null;
Output:输出:
Position
4
8
29
31
expected output:预期输出:
ID Position
1 4
1 8
1 29
1 31
2 8
2 15
-- --
No need for generate_series.不需要 generate_series。
select m.id
,sum (length (u.token) + length ('A')) over
(
partition by m.id
order by u.i
rows unbounded preceding
) - length ('A') + 1 as Position
from mixdatatable as m
cross join lateral
regexp_split_to_table (substring (datastring,'(.*)A'),'A')
with ordinality u(token,i)
+----+----------+
| id | position |
+----+----------+
| 1 | 4 |
+----+----------+
| 1 | 8 |
+----+----------+
| 1 | 29 |
+----+----------+
| 1 | 31 |
+----+----------+
| 2 | 8 |
+----+----------+
| 2 | 15 |
+----+----------+
| 2 | 31 |
+----+----------+
Please use below approch:请使用以下方法:
select cast(RIGHT(de.SRNO,10) as bigint) + 1 as SRNO from
(select RIGHT(SRNO,10) as SRNO ,SRNO as ACT FROM table1) de
left outer join
(select RIGHT(SRNO,10) as SRNO ,SRNO as ACT FROM table1) de1
on cast(RIGHT(de.SRNO,10) as bigint) + 1 = cast(RIGHT(de1.SRNO,10) as bigint)
where cast(RIGHT(de1.SRNO,10) as bigint) is null
ORDER BY SRNO asc
I think the fact that there are so many solutions shows well how powerful PostgreSQL's query language is.我认为有这么多解决方案的事实很好地说明了 PostgreSQL 的查询语言是多么强大。
Here is my solution:这是我的解决方案:
SELECT m.id, p.pos
FROM mixdatatable m
JOIN LATERAL (
SELECT row_number() OVER () AS n,
count(*) OVER () AS total,
sum(length(s)) OVER all_prev + count(s) OVER all_prev AS pos
FROM regexp_split_to_table(datastring, 'A') s
WINDOW all_prev AS (ROWS UNBOUNDED PRECEDING)
) p
ON p.n < p.total;
Here is another solution which turns each datastring into an array and uses the with ordinality
option to generate the index numbers:这是另一种将每个数据字符串转换为数组并使用
with ordinality
选项生成索引号的解决方案:
select m.id, t.pos
from mixdatatable m
cross join lateral unnest(string_to_array(m.datastring,null)) with ordinality as t(ch, pos)
where ch = 'A'
order by m.id, t.pos;
Online example: https://rextester.com/TAM31056在线示例: https : //rextester.com/TAM31056
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.