在postgres中找到新的线条字符

在数据库表中有几个条目具有多个行“名称”数据 . 我尝试从中找到单个换行符 .

SELECT
   id,
   strpos ( NAME, E'\n' ) AS Position_of_substring
FROM
   problems
WHERE
   strpos ( NAME, E'\n' ) > 0;

但是对于具有多于1个新行字符(\ n)的数据,它失败了 . 在名称数据中找到“n”个“n”的任何方法 .

回答(2)

2 years ago

这个给你一个字符串中包含 \n 的所有索引的列表 . 我不确定你是否期待这个结果:

demo:db<>fiddle

SELECT
    name,
    array_remove(                -- 5
        (array_agg(sum))::int[], -- 4
        length(name) + 1        
    )
FROM (
    -- 3
    SELECT 
        name, 
        SUM(length(lines) + 1) OVER (PARTITION BY name ORDER BY row_number)
    FROM (
        -- 2
        SELECT 
            *,
            row_number() OVER ()
        FROM (
            -- 1
            SELECT 
                name, 
                regexp_split_to_table(name, '\n') as lines 
            FROM problems
        )s
    )s
) s
GROUP BY name
  • \n 字符处拆分字符串 . 每个拆分部分现在都是临时表中的一行 .

  • 添加 row_count 以确保拆分零件的正确顺序

  • 这计算所有单个分割部分的长度 . (长度1)给出 \n 的位置 . SUM window function汇总了组中的所有值(原始文本) . 这就是订单相关的原因 . 例如:"abc\nde\nfgh"的前两个部分的长度为3和2.因此中断为4(abc = 3,1)和3(de = 2,1) . 但是第二部分中的第3部分并不是真正的索引,但如果总结这些值,则会得到正确的索引:4和7 .

  • 汇总这些结果

  • 如果(在我的例子中)最后一个字符始终是 \n 而您只对 \n 字符感兴趣,则可以删除聚合数组的最后一个条目 .

2 years ago

regexp_matches 将为每个匹配发出一行 . doc

SELECT
   id,
   strpos ( NAME, E'\n' ) AS Position_of_substring
FROM
   problems p
WHERE
   (select count(*) from regexp_matches(p.name,E'\n','g') ) = ?;