Saya punya tabel SQL Server yang berisi pengguna & nilai-nilai mereka. Untuk kesederhanaan's sake, memungkinkan hanya mengatakan ada 2 kolom - nama
& kelas
. Begitu khas-turut akan Nama: "John Doe", Kelas:"A".
I'm mencari satu pernyataan SQL yang akan menemukan persentase dari semua kemungkinan jawaban. (A, B, C, dll...) Juga, apakah ada cara untuk melakukan hal ini tanpa menentukan semua kemungkinan jawaban (open bidang teks - pengguna bisa memasukkan 'lulus/gagal', 'ada', dll...)
Hasil akhir I'm tempat ideal untuk: 5%, B: 15%, C: 40%, dll...
Saya telah diuji sebagai berikut dan ini tidak bekerja. Jawaban oleh gordyii dekat tapi memiliki kelipatan 100 di tempat yang salah dan hilang kurung.
Select Grade, (Count(Grade)* 100 / (Select Count(*) From MyTable)) as Score
From MyTable
Group By Grade
pilih Kelas, count() 100.0 / sum(count(*)) lebih dari() dari MyTable group by Kelas
pilih Kelas, count() 100.0 / (select count(*) from MyTable) dari MyTable group by Kelas;
dengan t(Kelas, GradeCount) sebagai ( pilih Kelas, count() dari MyTable group by Kelas ) pilih Kelas, GradeCount 100.0/(select sum(GradeCount) dari t) dari t;
Alih-alih menggunakan terpisah CTE untuk mendapatkan total, anda dapat menggunakan fungsi jendela tanpa "partisi dengan" klausa.
Jika anda menggunakan:
count(*)
untuk mendapatkan hitung untuk kelompok, anda dapat menggunakan:
sum(count(*)) over ()
untuk mendapatkan jumlah total.
Misalnya:
select Grade, 100. * count(*) / sum(count(*)) over ()
from table
group by Grade;
Hal ini cenderung menjadi lebih cepat dalam pengalaman saya, tapi saya pikir itu mungkin secara internal menggunakan tabel temp dalam beberapa kasus (I've melihat "Meja kerja" ketika berjalan dengan "set statistik io on").
EDIT: I'm tidak yakin jika saya contoh query adalah apa yang anda cari, saya hanya menggambarkan bagaimana fungsi windowing bekerja.
Yang anda butuhkan untuk kelompok di kelas lapangan. Query ini akan memberikan anda apa yang anda cari dalam setiap database.
Select Grade, CountofGrade / sum(CountofGrade) *100
from
(
Select Grade, Count(*) as CountofGrade
From Grades
Group By Grade) as sub
Group by Grade
Anda harus menentukan sistem anda're menggunakan.
Anda harus menghitung total nilai Jika SQL 2005 anda dapat menggunakan CTE
WITH Tot(Total) (
SELECT COUNT(*) FROM table
)
SELECT Grade, COUNT(*) / Total * 100
--, CONVERT(VARCHAR, COUNT(*) / Total * 100) + '%' -- With percentage sign
--, CONVERT(VARCHAR, ROUND(COUNT(*) / Total * 100, -2)) + '%' -- With Round
FROM table
GROUP BY Grade
Saya hanya menggunakan ini ketika pernah saya butuhkan untuk bekerja di luar persentase..
ROUND(CAST((Numerator * 100.0 / Denominator) AS FLOAT), 2) AS Percentage
Perhatikan bahwa 100.0 kembali desimal, sedangkan 100's sendiri akan mengumpulkan hasilnya ke seluruh nomor terdekat, bahkan dengan ROUND() fungsi!
Berikut harus bekerja
ID - Key
Grade - A,B,C,D...
EDIT: Pindah * 100
dan menambahkan 1.0
untuk memastikan bahwa itu doesn't melakukan pembagian integer
Select
Grade, Count(ID) * 100.0 / ((Select Count(ID) From MyTable) * 1.0)
From MyTable
Group By Grade
Ini adalah, saya percaya, sebuah solusi umum, meskipun saya diuji menggunakan IBM Informix Dynamic Server 11.50.FC3. Query berikut:
SELECT grade,
ROUND(100.0 * grade_sum / (SELECT COUNT(*) FROM grades), 2) AS pct_of_grades
FROM (SELECT grade, COUNT(*) AS grade_sum
FROM grades
GROUP BY grade
)
ORDER BY grade;
memberikan output sebagai berikut pada data uji yang ditunjukkan di bawah aturan horizontal. Yang BULAT
fungsi dapat DBMS yang spesifik, tapi (mungkin) tidak. (Perhatikan bahwa saya berubah 100 100,0 untuk memastikan bahwa perhitungan yang terjadi dengan menggunakan non-integer DESIMAL, ANGKA - aritmatika; lihat komentar-komentar, dan terima kasih untuk Thunder.)
grade pct_of_grades
CHAR(1) DECIMAL(32,2)
A 32.26
B 16.13
C 12.90
D 12.90
E 9.68
F 16.13
CREATE TABLE grades
(
id VARCHAR(10) NOT NULL,
grade CHAR(1) NOT NULL CHECK (grade MATCHES '[ABCDEF]')
);
INSERT INTO grades VALUES('1001', 'A');
INSERT INTO grades VALUES('1002', 'B');
INSERT INTO grades VALUES('1003', 'F');
INSERT INTO grades VALUES('1004', 'C');
INSERT INTO grades VALUES('1005', 'D');
INSERT INTO grades VALUES('1006', 'A');
INSERT INTO grades VALUES('1007', 'F');
INSERT INTO grades VALUES('1008', 'C');
INSERT INTO grades VALUES('1009', 'A');
INSERT INTO grades VALUES('1010', 'E');
INSERT INTO grades VALUES('1001', 'A');
INSERT INTO grades VALUES('1012', 'F');
INSERT INTO grades VALUES('1013', 'D');
INSERT INTO grades VALUES('1014', 'B');
INSERT INTO grades VALUES('1015', 'E');
INSERT INTO grades VALUES('1016', 'A');
INSERT INTO grades VALUES('1017', 'F');
INSERT INTO grades VALUES('1018', 'B');
INSERT INTO grades VALUES('1019', 'C');
INSERT INTO grades VALUES('1020', 'A');
INSERT INTO grades VALUES('1021', 'A');
INSERT INTO grades VALUES('1022', 'E');
INSERT INTO grades VALUES('1023', 'D');
INSERT INTO grades VALUES('1024', 'B');
INSERT INTO grades VALUES('1025', 'A');
INSERT INTO grades VALUES('1026', 'A');
INSERT INTO grades VALUES('1027', 'D');
INSERT INTO grades VALUES('1028', 'B');
INSERT INTO grades VALUES('1029', 'A');
INSERT INTO grades VALUES('1030', 'C');
INSERT INTO grades VALUES('1031', 'F');
Anda dapat menggunakan subselect anda dari query (belum teruji dan tidak yakin mana yang lebih cepat):
SELECT Grade, COUNT(*) / TotalRows
FROM (SELECT Grade, COUNT(*) As TotalRows
FROM myTable) Grades
GROUP BY Grade, TotalRows
Atau
SELECT Grade, SUM(PartialCount)
FROM (SELECT Grade, 1/COUNT(*) AS PartialCount
FROM myTable) Grades
GROUP BY Grade
Atau
SELECT Grade, GradeCount / SUM(GradeCount)
FROM (SELECT Grade, COUNT(*) As GradeCount
FROM myTable
GROUP BY Grade) Grades
Anda juga dapat menggunakan stored procedure (maaf untuk Firebird sintaks):
SELECT COUNT(*)
FROM myTable
INTO :TotalCount;
FOR SELECT Grade, COUNT(*)
FROM myTable
GROUP BY Grade
INTO :Grade, :GradeCount
DO
BEGIN
Percent = :GradeCount / :TotalCount;
SUSPEND;
END
Di setiap versi sql server anda bisa menggunakan variabel total dari semua nilai seperti ini:
declare @countOfAll decimal(18, 4)
select @countOfAll = COUNT(*) from Grades
select
Grade, COUNT(*) / @countOfAll * 100
from Grades
group by Grade