テーブル内のデータの出現回数をカウントする列を作成する最良の方法は何ですか?テーブルは1つの列でグループ化する必要があります。
私は見た
_SELECT
sum(CASE WHEN question1 = 0 THEN 1 ELSE 0 END) AS ZERO,
sum(CASE WHEN question1 = 1 THEN 1 ELSE 0 END) AS ONE,
sum(CASE WHEN question1 = 2 THEN 1 ELSE 0 END) AS TWO,
category
FROM reviews
GROUP BY category
_
ここで、question1の値は0、1、または2のいずれかです。
count(CASE WHEN question1 = 0 THEN 1)
を使用したバージョンも確認しました
ただし、question1の可能な値の数が増えると、これは書きにくくなります。このクエリを記述して、おそらくパフォーマンスを最適化する便利な方法はありますか?
PS。私のデータベースはPostgreSQLです
Postgres 9.4では、新しい、よりクリーンな集約FILTER
オプションがあります:
_SELECT category
, count(*) FILTER (WHERE question1 = 0) AS zero
, count(*) FILTER (WHERE question1 = 1) AS one
, count(*) FILTER (WHERE question1 = 2) AS two
FROM reviews
GROUP BY 1;
_
新しいFILTER
句の詳細:
必要に応じてshort:
_SELECT category
, count(question1 = 0 OR NULL) AS zero
, count(question1 = 1 OR NULL) AS one
, count(question1 = 2 OR NULL) AS two
FROM reviews
GROUP BY 1;
_
考えられるバリアントの概要:
crosstab()
は、最高のパフォーマンスをもたらし、オプションのリストが長いほど短くなります。
_SELECT * FROM crosstab(
'SELECT category, question1, count(*)::int AS ct
FROM reviews
GROUP BY 1, 2
ORDER BY 1, 2'
, 'VALUES (0), (1), (2)'
) AS ct (category text, zero int, one int, two int);
_
詳細な説明:
「私にとって」「最良の」方法は、次のようなクエリを記述することです。
SELECT
category,
question1,
count(*)
FROM reviews
GROUP BY category, question1
次に、このデータを使用して、アプリケーションロジックでテーブルを描画します。
その他のオプションは、すべてのグループ化結果に1つのJSON列を使用することです。これは次のような結果になります:
category1 | {"zero": 1, "one": 3, "two": 5}
category2 | {"one": 7, "two": 4}
等々。
このオプションのクエリは、json_build_object
およびjson_agg
を使用して前のオプションから構築できます。このオプションの最良の点-事前に、可能なquestion1
値の数を知る必要はありません。