Cara menggunakan hitungan dan kelompokkan pada pernyataan pilih yang sama


223

Saya memiliki kueri pemilihan sql yang memiliki grup oleh. Saya ingin menghitung semua catatan setelah grup dengan pernyataan. Apakah ada cara untuk ini langsung dari sql? Misalnya, memiliki tabel dengan pengguna, saya ingin memilih kota yang berbeda dan jumlah total pengguna

select town, count(*) from user
group by town

Saya ingin memiliki kolom dengan semua kota dan lainnya dengan jumlah pengguna di semua baris.

Contoh hasil untuk memiliki 3 kota dan 58 pengguna secara total adalah:

Town         Count
Copenhagen   58
NewYork      58
Athens       58

Anda berarti Anda ingin hasil Anda ditetapkan memiliki 2 hitungan, satu untuk kota dan satu untuk pengguna?
Leslie

2
Jadi Anda ingin satu baris untuk setiap kota, dan di setiap baris, kolom 2 berisi jumlah total semua pengguna? Jadi kolom 2 memiliki nilai yang sama untuk setiap baris? Jika Anda mengedit untuk memasukkan data sampel dan output yang diperlukan, kami akan dapat memberikan apa yang Anda inginkan.
AakashM

Anda AakashM benar! Saya baru saja mengeditnya.
Stavros


1
Peringatan kepada pembaca: Sebagian besar jawaban gagal memberikan jawaban untuk kueri yang diperbarui.
Rick James

Jawaban:


271

Ini akan melakukan apa yang Anda inginkan (daftar kota, dengan jumlah pengguna di masing-masing):

select town, count(town) 
from user
group by town

Anda dapat menggunakan sebagian besar fungsi agregat saat menggunakan GROUP BY.

Pembaruan (mengikuti perubahan pertanyaan dan komentar)

Anda dapat mendeklarasikan variabel untuk jumlah pengguna dan mengaturnya ke jumlah pengguna kemudian pilih dengan itu.

DECLARE @numOfUsers INT
SET @numOfUsers = SELECT COUNT(*) FROM user

SELECT DISTINCT town, @numOfUsers
FROM user

itulah yang ditulis OP? nvm, saya melihat perbedaan Anda, Anda menghitung Town not * ....
Leslie

@ Leslie - tidak ada perbedaan antara dua pertanyaan. Mereka akan mengembalikan set hasil yang sama. Saya hanya tidak suka penggunaan *... OP menjawab pertanyaannya sendiri, tetapi tampaknya bahkan tidak mengujinya, saya hanya memvalidasi bahwa itu benar :) fredosaurus.com/notes-db/select/groupby.html
Oded

Sekali lagi bukan apa yang saya harapkan, tetapi tampaknya ini adalah solusi terbaik ..;) Terima kasih
Stavros

149

Anda bisa menggunakan COUNT(DISTINCT ...):

SELECT COUNT(DISTINCT town) 
FROM user

3
berfungsi sebagai pesona ... harus dipilih jawaban utama .. kecuali beberapa penyelidikan bahwa ini tidak baik.
Victor

2
Saya pikir maksud mereka jika Anda memasukkan COUNT (DISTINCT town) dalam klausa WHERE. Itu karena itu adalah fungsi agregat dan perlu disediakan dalam klausa HAVING. Query SQL ini menyesatkan beberapa orang karena SELECT COUNT (DISTINCT town) berubah menjadi GROUP BY implisit, karena kata kunci COUNT dan DISTINCT, setiap kata kunci pada mereka sendiri juga secara implisit akan dikelompokkan.
A. Greensmith

Terima kasih. Suara positif. Persis apa yang dibutuhkan - kelompok + hitung dalam satu operasi dan dapatkan satu baris dalam hasil.
Hijau

Sial .. Saya tidak tahu itu mungkin!
Hugo S. Mendes

1
@milkovsky - Tidak, Anda tidak harus menghapusnya. Saya hanya merasa kesal karena Pertanyaan ini ditambah banyak Jawaban telah bercabang menjadi dua masalah yang berbeda . Jawaban Anda menyimpang dalam dua cara - tidak ada townkolom, dan itu COUNTssalah (kota bukan pengguna).
Rick James

37

Cara lainnya adalah:

/* Number of rows in a derived table called d1. */
select count(*) from
(
  /* Number of times each town appears in user. */
  select town, count(*)
  from user
  group by town
) d1

5
perlu alias kalau tidak tidak akan bekerja di mysql. pilih hitungan (*) dari ()
agr

4

Dengan Oracle Anda dapat menggunakan fungsi analitik:

select town, count(town), sum(count(town)) over () total_count from user
group by town

Pilihan Anda yang lain adalah menggunakan subquery:

select town, count(town), (select count(town) from user) as total_count from user
group by town

sesuatu seperti yang terakhir akan bekerja, tetapi saya ingin melihat apakah ada solusi lain ..
Stavros

Dan tidak bisakah Anda menggunakan opsi (fungsi analitik) pertama? Platform basis data apa yang Anda gunakan?
Tommi

@Stavros: Yang terakhir lambat
Michael Buen

4

Jika Anda ingin memesan berdasarkan hitungan (terdengar sederhana tetapi saya tidak dapat menemukan jawaban di tumpukan cara melakukan itu) yang dapat Anda lakukan:

        SELECT town, count(town) as total FROM user
        GROUP BY town ORDER BY total DESC

4

Sepuluh jawaban yang tidak dihapus; kebanyakan tidak melakukan apa yang diminta pengguna. Sebagian besar Jawaban salah membaca pertanyaan dengan berpikir bahwa ada 58 pengguna di masing-masing kota alih-alih total 58. Bahkan beberapa yang benar pun tidak optimal.

mysql> flush status;
Query OK, 0 rows affected (0.00 sec)

SELECT  province, total_cities
    FROM       ( SELECT  DISTINCT province  FROM  canada ) AS provinces
    CROSS JOIN ( SELECT  COUNT(*) total_cities  FROM  canada ) AS tot;
+---------------------------+--------------+
| province                  | total_cities |
+---------------------------+--------------+
| Alberta                   |         5484 |
| British Columbia          |         5484 |
| Manitoba                  |         5484 |
| New Brunswick             |         5484 |
| Newfoundland and Labrador |         5484 |
| Northwest Territories     |         5484 |
| Nova Scotia               |         5484 |
| Nunavut                   |         5484 |
| Ontario                   |         5484 |
| Prince Edward Island      |         5484 |
| Quebec                    |         5484 |
| Saskatchewan              |         5484 |
| Yukon                     |         5484 |
+---------------------------+--------------+
13 rows in set (0.01 sec)

SHOW session status LIKE 'Handler%';

+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Handler_commit             | 1     |
| Handler_delete             | 0     |
| Handler_discover           | 0     |
| Handler_external_lock      | 4     |
| Handler_mrr_init           | 0     |
| Handler_prepare            | 0     |
| Handler_read_first         | 3     |
| Handler_read_key           | 16    |
| Handler_read_last          | 1     |
| Handler_read_next          | 5484  |  -- One table scan to get COUNT(*)
| Handler_read_prev          | 0     |
| Handler_read_rnd           | 0     |
| Handler_read_rnd_next      | 15    |
| Handler_rollback           | 0     |
| Handler_savepoint          | 0     |
| Handler_savepoint_rollback | 0     |
| Handler_update             | 0     |
| Handler_write              | 14    |  -- leapfrog through index to find provinces  
+----------------------------+-------+

Dalam konteks OP:

SELECT  town, total_users
    FROM       ( SELECT  DISTINCT town  FROM  canada ) AS towns
    CROSS JOIN ( SELECT  COUNT(*) total_users  FROM  canada ) AS tot;

Karena hanya ada satu baris dari tot, baris CROSS JOINini tidak seberat yang seharusnya.

Pola yang biasa adalah COUNT(*)bukannya COUNT(town). Yang terakhir menyiratkan memeriksa townuntuk tidak nol, yang tidak perlu dalam konteks ini.


2

Anda dapat menggunakan DISTINCT di dalam COUNT seperti yang dikatakan milkovsky

dalam kasus saya:

select COUNT(distinct user_id) from answers_votes where answer_id in (694,695);

Ini akan menarik jumlah suara jawaban yang dianggap sama dengan user_id sebagai satu hitungan


2

Saya tahu ini adalah posting lama, di SQL Server:

select  isnull(town,'TOTAL') Town, count(*) cnt
from    user
group by town WITH ROLLUP

Town         cnt
Copenhagen   58
NewYork      58
Athens       58
TOTAL        174

5
Tidak ada yang salah dengan menjawab posting lama. Namun, harap sertakan penjelasan tentang kode Anda dan juga kode itu sendiri.
Shelvacu

Setara MySQL ( IFNULLbukan ISNULL) mengarah ke nomor yang berbeda untuk setiap kota; pengguna menginginkan total. Menurut Pertanyaan, 58, bukan 174, adalah total.
Rick James

1

Jika Anda ingin memilih kota dan jumlah total pengguna, Anda dapat menggunakan pertanyaan ini di bawah ini:

SELECT Town, (SELECT Count(*) FROM User) `Count` FROM user GROUP BY Town;

Ini mengasumsikan (mungkin secara wajar) tidak ada duplikat "pengguna" di User.
Rick James

1

jika Anda ingin menggunakan Select All Query With Count Option, coba ini ...

 select a.*, (Select count(b.name) from table_name as b where Condition) as totCount from table_name  as a where where Condition

Terima kasih atas cuplikan kode ini, yang mungkin memberikan bantuan terbatas dan segera. Penjelasan yang tepat akan sangat meningkatkan nilai jangka panjangnya dengan menunjukkan mengapa ini adalah solusi yang baik untuk masalah ini, dan akan membuatnya lebih bermanfaat bagi pembaca masa depan dengan pertanyaan lain yang serupa. Harap edit jawaban Anda untuk menambahkan beberapa penjelasan, termasuk asumsi yang Anda buat.
Toby Speight

0

Coba kode berikut:

select ccode, count(empno) 
from company_details 
group by ccode;

kami menggunakan kode ini untuk menemukan berapa total karyawan untuk perhitungan hari ini di masing-masing dan setiap kode (contoh perusahaan) contoh: jumlah (empno) adalah 1839 untuk kode 1 dan jumlah (empno) adalah 9421 untuk kode 47.
balajibran
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.