Možná jsem přišel s řešením:
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
Trik funguje takto:
- Změňte typ řádku na jeho textovou reprezentaci.
- Změřte délku znaků.
- Nahraďte znak, který chcete spočítat, a změřte změnu délky.
- Vypočítejte délku původního řádku v dílčím výběru pro opakované použití.
To vyžaduje P, F, I
nejsou přítomny nikde jinde v řadě. Pomocí dílčího výběru vylučte jakékoli další sloupce, které by mohly rušit.
Testováno v 8.4 - 9.1. PostgreSQL 7.4 už dnes nikdo nepoužívá, budete se muset otestovat sami. Používám pouze základní funkce, ale nejsem si jistý, zda je přetypování typu řádku na text v 7.4 proveditelné. Pokud to nefunguje, budete muset zřetězit všechny testovací sloupce jednou ručně:
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
To vyžaduje, aby všechny sloupce byly NOT NULL
.