Talvez eu tenha encontrado uma solução:
SELECT id
,l - length(replace(t, 'P', '')) AS nr_p
,l - length(replace(t, 'F', '')) AS nr_f
,l - length(replace(t, 'I', '')) AS nr_i
FROM (SELECT id, test::text AS t, length(test::text) AS l FROM test) t
O truque funciona assim:
- Transforme o tipo de linha em sua representação de texto.
- Meça o comprimento do caractere.
- Substitua o caractere que deseja contar e meça a mudança de comprimento.
- Calcule o comprimento da linha original na subseleção para uso repetido.
Isso requer que
P, F, I
não estão presentes em nenhum outro lugar na linha. Use uma subseleção para excluir quaisquer outras colunas que possam interferir. Testado em 8.4 - 9.1. Ninguém usa mais o PostgreSQL 7.4 hoje em dia, você terá que testar a si mesmo. Eu só uso funções básicas, mas não tenho certeza se converter o tipo de linha em texto é viável em 7.4. Se isso não funcionar, você terá que concatenar todas as colunas de teste uma vez manualmente:
SELECT id
,length(t) - length(replace(t, 'P', '')) AS nr_p
,length(t) - length(replace(t, 'F', '')) AS nr_f
,length(t) - length(replace(t, 'I', '')) AS nr_i
FROM (SELECT id, test1||test2||test3||test4 AS t FROM test) t
Isso requer que todas as colunas sejam
NOT NULL
.