Може да съм измислил решение:
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
Трикът работи по следния начин:
- Трансформирайте типа ред в неговото текстово представяне.
- Измерете дължината на знаците.
- Заменете знака, който искате да преброите, и измерете промяната в дължината.
- Изчислете дължината на оригиналния ред в подизбора за многократна употреба.
Това изисква P, F, I
не присъстват никъде другаде в реда. Използвайте подизбор, за да изключите всички други колони, които биха могли да пречат.
Тествано в 8.4 - 9.1. Никой вече не използва PostgreSQL 7.4 в днешно време, ще трябва да тествате сами. Използвам само основни функции, но не съм сигурен дали прехвърлянето на типа ред към текст е възможно в 7.4. Ако това не работи, ще трябва да свържете всички тестови колони веднъж на ръка:
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
Това изисква всички колони да са NOT NULL
.