Cara menghitung bila tidak mengetahui tipe tertentu

Saya sedang mengerjakan tabel seperti ini:

id type
1 A
2 A
3 B
4 C
5 C

Saya ingin menghitung jumlah id untuk setiap jenis, dan mendapatkan tabel seperti ini.

type_a type_b type_c
2 1 2

Apa yang saya lakukan adalah

SELECT 
    SUM(CASE WHEN type = 'A' THEN 1 ELSE 0 END) AS type_a,
    SUM(CASE WHEN type = 'B' THEN 1 ELSE 0 END) AS type_b,
    SUM(CASE WHEN type = 'C' THEN 1 ELSE 0 END) AS type_c
FROM myTable

Pertanyaan saya adalah, jika saya tidak tahu ada berapa jenisnya, dan tidak bisa mencantumkan semua kasus secara spesifik, bagaimana saya bisa mencapainya?


person Erin Liu    schedule 16.04.2021    source sumber
comment
Akan lebih mudah untuk mengembalikan hasilnya dalam dua kolom: Tipe, Hitung.   -  person Janez Kuhar    schedule 16.04.2021
comment
maka Anda perlu menggunakan sql dinamis   -  person eshirvana    schedule 16.04.2021
comment
Apakah ini menjawab pertanyaan Anda? Kueri pivot dinamis menggunakan PostgreSQL 9.3   -  person PM 77-1    schedule 16.04.2021


Jawaban (2)


Anda mencari tabulasi silang atau tabel pivot. Saya menambahkan tag.
Namun:

jika saya tidak tahu ada berapa jenisnya, dan tidak bisa mencantumkan semua kasus secara spesifik, bagaimana saya bisa mencapainya?

Pada dasarnya, hal itu tidak mungkin dalam satu kueri SQL karena SQL menuntut untuk mengetahui jumlah kolom hasil pada waktu panggilan. Itu tidak dapat mengembalikan jumlah kolom dinamis pada prinsipnya.

Ada berbagai solusi dengan tipe polimorfik, atau dengan tipe dokumen seperti json, jsonb, hstore atau xml, atau mengembalikan array alih-alih kolom individual ...

Namun untuk mendapatkan apa yang Anda minta, kolom khusus yang jumlahnya tidak diketahui, Anda memerlukan alur kerja dua langkah. Menyukai:

  1. Bangun kueri secara dinamis (menentukan tipe pengembalian).
  2. Jalankan itu.

Terkait:

Oleh karena itu, jika kasus Anda sederhana dan Anda menangani banyak jenis yang diketahui, Anda dapat melakukan provisi berlebihan. Dengan kueri crosstab() yang lebih cepat, atau dengan agregasi bersyarat sederhana seperti yang Anda miliki, menjadi lebih elegan dan efisien dengan klausa agregat FILTER:

SELECT count(*) FILTER (WHERE type = 'A') AS type_a
     , count(*) FILTER (WHERE type = 'B') AS type_b
     , count(*) FILTER (WHERE type = 'C') AS type_c
     , count(*) FILTER (WHERE type = 'D') AS type_d
     -- that's all folks!
FROM   tbl;

Ketik tanpa entri laporan 0 (count() tidak pernah mengembalikan NULL) yang mana akan tetap benar.

Tentu saja tidak berfungsi untuk tipe yang tidak diketahui.

person Erwin Brandstetter    schedule 17.04.2021

Jika saya memahami Anda dengan benar, yang Anda inginkan hanyalah COUNT sederhana:

SELECT
    type
    ,COUNT(id)
FROM myTable
GROUP BY type
person Don R    schedule 16.04.2021
comment
Ada beberapa kolom lagi yang ingin saya tambahkan. Misalnya: hitungan, persentase, dll. dan inginnya, untuk setiap kolom, itu adalah jenisnya, untuk baris pertama, itu adalah jumlah setiap jenis, dan untuk baris kedua, itu adalah persentase dari setiap jenis. (persentase = jumlah setiap jenis / jumlah total id). - person Erin Liu; 17.04.2021