私は解決策を思いついたかもしれません:
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でテスト済み。最近では、PostgreSQL7.4を使用する人は誰もいません。自分でテストする必要があります。基本的な関数しか使用していませんが、7.4で行タイプをテキストにキャストできるかどうかはわかりません。それでも問題が解決しない場合は、すべてのテスト列を手動で1回連結する必要があります。
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
である必要があります 。