Tôi có thể đã nghĩ ra một giải pháp:
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
Thủ thuật hoạt động như thế này:
- Chuyển đổi kiểu hàng thành biểu diễn văn bản của nó.
- Đo độ dài ký tự.
- Thay thế ký tự bạn muốn đếm và đo lường sự thay đổi về độ dài.
- Tính độ dài của hàng gốc trong lựa chọn con để sử dụng nhiều lần.
Điều này yêu cầu P, F, I
không có mặt ở nơi nào khác trong hàng. Sử dụng một lựa chọn phụ để loại trừ bất kỳ cột nào khác có thể gây trở ngại.
Thử nghiệm trong 8.4 - 9.1. Ngày nay không ai sử dụng PostgreSQL 7.4 nữa, bạn sẽ phải tự kiểm tra. Tôi chỉ sử dụng các chức năng cơ bản, nhưng tôi không chắc liệu việc truyền kiểu hàng thành văn bản có khả thi trong 7.4 hay không. Nếu điều đó không hiệu quả, bạn sẽ phải nối tất cả các cột thử nghiệm một lần bằng tay:
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
Điều này yêu cầu tất cả các cột phải NOT NULL
.