Być może znalazłem rozwiązanie:
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
Sztuczka działa tak:
- Przekształć typ wiersza w jego reprezentację tekstową.
- Zmierz długość znaków.
- Zastąp znak, który chcesz policzyć i zmierz zmianę długości.
- Oblicz długość oryginalnego wiersza w podselekcji do wielokrotnego użycia.
Wymaga to P, F, I
nie są obecne nigdzie indziej w rzędzie. Użyj podwyboru, aby wykluczyć wszelkie inne kolumny, które mogą kolidować.
Testowane w 8.4 - 9.1. Nikt już nie używa PostgreSQL 7.4 w dzisiejszych czasach, musisz sam to przetestować. Używam tylko podstawowych funkcji, ale nie jestem pewien, czy rzutowanie typu rowtype na tekst jest wykonalne w wersji 7.4. Jeśli to nie zadziała, będziesz musiał połączyć wszystkie kolumny testowe raz ręcznie:
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 wymaga, aby wszystkie kolumny były NOT NULL
.