Hitung jumlah catatan yang dikembalikan oleh kelompok oleh

144

Bagaimana cara menghitung jumlah rekaman yang dikembalikan oleh grup menurut kueri,

Misalnya:

select count(*) 
from temptable
group by column_1, column_2, column_3, column_4

Beri aku,

1
1
2

Saya perlu menghitung catatan di atas untuk mendapatkan 1 + 1 + 1 = 3.

Chris
sumber
3
@LorenVS: Tapi itu akan memberi saya hitungan jumlah rekaman di tabel. Saya membutuhkan jumlah catatan setelah grup terjadi.
Chris
3
Kelompok oleh tidak mengubah jumlah baris. 1 + 1 + 2 (dalam contoh Anda) akan menjadi jumlah baris dalam tabel. Apakah Anda mencari 3? Jumlah kelompok yang berbeda?
LorenVS
2
Cara lain untuk merumuskan pertanyaan: bagaimana cara memilih jumlah tingkat pengelompokan yang berbeda untuk kueri tertentu?
Julian
Tidak selalu jelas mengapa pengguna mengajukan pertanyaan, tetapi saya sampai di sini karena saya menguji apakah kolom dalam tampilan adalah kandidat kunci utama atau kunci kombinasi. Waktu habis "pilih jumlah (COLUMNNAME berbeda) dari VIEWNAME", di mana kelompokkan menurut karya jika saya bisa mendapatkan total.
Ken Forslund

Jawaban:

172

Anda dapat melakukan keduanya dalam satu kueri menggunakan klausa OVER di COUNT lainnya

select
    count(*) RecordsPerGroup,
    COUNT(*) OVER () AS TotalRecords
from temptable
group by column_1, column_2, column_3, column_4
gbn
sumber
Saya tahu ini adalah pertanyaan SQL-Server, tetapi untuk referensi: Ini tidak berfungsi pada DB / 2 (dalam kasus saya di IBM iSeries). Lihat komentar saya pada jawaban
Thomas
Bagaimana saya menggemakan angka yang dihitung itu?
McDan Garrett
1
Sisi buruk dari solusi ini adalah memberikan jawaban beberapa kali (untuk setiap kombinasi column_1, column_2, column_3, column_4). Ini mungkin atau mungkin tidak menjadi efek samping yang signifikan, tergantung pada bagaimana Anda memproses hasilnya.
cartbeforehorse
5
Untuk mengembalikan jumlah record saja, tambahkan top pilih (1) count (*) over () as ....
Guilherme Campos Hazan
3
Dalam kasus saya menggunakan TOP (1) COUNT ( ) OVER () memiliki kinerja kueri yang buruk. Karena saya hanya membutuhkan jumlah grup, saya mengubahnya menjadi DISTINCT COUNT ( ) OVER (), dan kinerja kueri meningkat secara dramatis.
Joe Aldrich
75

Solusi paling sederhana adalah dengan menggunakan tabel turunan:

Select Count(*)
From    (
        Select ...
        From TempTable
        Group By column_1, column_2, column_3, column_4
        ) As Z

Solusi lain adalah dengan menggunakan Count Distinct:

Select ...
    , ( Select Count( Distinct column_1, column_2, column_3, column_4 )
        From TempTable ) As CountOfItems
From TempTable
Group By column_1, column_2, column_3, column_4
Thomas
sumber
Jawaban pertama juga berfungsi pada DB / 2, tetapi untuk beberapa alasan perlu tambahan AS TMP agar berfungsi (seperti troutinator yang ditambahkan)
Bjinse
5
@Bjinse - Beberapa DBMS akan mengharuskan semua tabel turunan memiliki alias. Mereka semua akan menerimanya jadi tidak ada salahnya untuk memasukkannya. Saya akan menambahkannya ke jawaban saya.
Thomas
26

Saya tahu ini agak terlambat, tetapi tidak ada yang menyarankan ini:

select count ( distinct column_1, column_2, column_3, column_4) 
from   temptable

Ini berfungsi di Oracle setidaknya - Saat ini saya tidak memiliki database lain untuk mengujinya, dan saya tidak begitu akrab dengan sintaks T-Sql dan MySQL.

Selain itu, saya tidak sepenuhnya yakin apakah lebih efisien dalam parser untuk melakukannya dengan cara ini, atau apakah solusi orang lain untuk menyusun pernyataan pilih lebih baik. Tapi saya menemukan yang ini lebih elegan dari perspektif pengkodean.

kereta kuda sebelumnya
sumber
Thomas menambahkan solusi Anda ke jawabannya. Bagaimanapun. Saya tidak akan merekomendasikan melakukan ini karena alasan pemeliharaan, solusi lain jauh lebih baik.
Răzvan Flavius ​​Panda
@ RăzvanFlaviusPanda 1. Mengapa? Apa yang lebih baik dari solusi lainnya? Nesting SQL lebih bertele-tele dan di mata saya, lebih berantakan dan lebih sulit untuk dipahami (ergo lebih sulit untuk dipertahankan dalam arti dukungan). Saya mengerti bahwa Anda mungkin memiliki preferensi untuk cara lain, tetapi itu bukan alasan untuk "merekomendasikan" ini daripada preferensi orang lain. Thomas memang membuat saran serupa, ya, tetapi sekali lagi dia membuatnya tampak seolah-olah menyarangkan SQL adalah bagian penting dari solusi, yang sebenarnya bukan.
cartbeforehorse
12

Saya mencoba untuk mencapai hal yang sama tanpa subquery dan bisa mendapatkan hasil yang diinginkan seperti di bawah ini

SELECT DISTINCT COUNT(*) OVER () AS TotalRecords
FROM temptable
GROUP BY column_1, column_2, column_3, column_4
Manish Mulani
sumber
4

CTE bekerja untuk saya:

with cte as (
  select 1 col1
  from temptable
  group by column_1
)

select COUNT(col1)
from cte;
SQL Pete
sumber
3

Bagaimana tentang:

SELECT count(column_1)
FROM
    (SELECT * FROM temptable
    GROUP BY column_1, column_2, column_3, column_4) AS Records
PedroC88
sumber
1

Anda bisa melakukan:

select sum(counts) total_records from (
    select count(*) as counts
    from temptable
    group by column_1, column_2, column_3, column_4
) as tmp
troutinator
sumber
1

Di PostgreSQL ini berfungsi untuk saya:

select count(count.counts) 
from 
    (select count(*) as counts 
     from table 
     group by concept) as count;
omar
sumber
1

Bisakah Anda menjalankan kode berikut di bawah ini. Ini bekerja di Oracle.

SELECT COUNT(COUNT(*))
FROM temptable
GROUP BY column_1, column_2, column_3, column_4
Arif
sumber
1
Tidak dapat menjalankan agregat di dalam agregat di sql-server.
A.Greensmith
0

Anda juga bisa mendapatkan kueri di bawah ini

select column_group_by,count(*) as Coulm_name_to_be_displayed from Table group by Column;

-- For example:
select city,count(*) AS Count from people group by city
Nitish Sahoo
sumber
0

Coba kueri ini:

select top 1 TotalRows = count(*) over () 
from yourTable
group by column1, column2
Marimuthu Shanmugasundaram
sumber
0

Mengikuti untuk PrestoDb , di mana FirstField dapat memiliki beberapa nilai:

select *
            , concat(cast(cast((ThirdTable.Total_Records_in_Group * 100 / ThirdTable.Total_Records_in_baseTable) as DECIMAL(5,2)) as varchar), '%') PERCENTage
from 
(
    SELECT FirstTable.FirstField, FirstTable.SecondField, SecondTable.Total_Records_in_baseTable, count(*) Total_Records_in_Group
    FROM BaseTable FirstTable
    JOIN (
            SELECT FK1, count(*) AS Total_Records_in_baseTable 
            FROM BaseTable
            GROUP BY FK1
        ) SecondTable
    ON FirstTable.FirstField = SecondTable.FK1
    GROUP BY FirstTable.FirstField, FirstTable.SecondField, SecondTable.Total_Records_in_baseTable
    ORDER BY FirstTable.FirstField, FirstTable.SecondField
) ThirdTable
SUKUMAR S
sumber
-1

Bagaimana jika menggunakan fungsi partisi COUNT OVER (PARTITION BY {column to group by}) di SQL Server?

Misalnya, jika Anda ingin mengelompokkan penjualan produk berdasarkan ItemID dan Anda ingin menghitung setiap ItemID yang berbeda, cukup gunakan:

SELECT
{columns you want} ,
COUNT(ItemID) OVER (PARTITION BY ItemID) as BandedItemCount ,
{more columns you want}... ,
FROM {MyTable}

Jika Anda menggunakan pendekatan ini, Anda bisa membiarkan GROUP BY keluar dari gambar - dengan asumsi Anda ingin mengembalikan seluruh daftar (seperti yang mungkin Anda lakukan report banding di mana Anda perlu mengetahui seluruh hitungan item yang akan Anda band tanpa harus untuk menampilkan seluruh kumpulan data, yaitu Layanan Pelaporan).

Johnny B
sumber
Nilai apa BandedItemCountsebenarnya yang akan terkandung? Apakah itu berbeda di antara baris keluaran? Penanya sedang mencari jumlah tingkat pengelompokan yang berbeda.
Julian