回答:
私は以下をテストしましたが、これはうまくいきます。gordyiiの答えは近いですが、間違った場所で100の乗算があり、括弧が欠けていました。
Select Grade, (Count(Grade)* 100 / (Select Count(*) From MyTable)) as Score
From MyTable
Group By Grade
最も効率的です(over()を使用)。
select Grade, count(*) * 100.0 / sum(count(*)) over()
from MyTable
group by Grade
ユニバーサル(任意のSQLバージョン)。
select Grade, count(*) * 100.0 / (select count(*) from MyTable)
from MyTable
group by Grade;
CTEを使用すると、最も効率が悪くなります。
with t(Grade, GradeCount)
as
(
select Grade, count(*)
from MyTable
group by Grade
)
select Grade, GradeCount * 100.0/(select sum(GradeCount) from t)
from t;
cast((count(*) / (sum(count(*)) over() / 100)) AS DECIMAL(18, 2)) as Percentage
over()
Postgresql 10
別個のCTEを使用して合計を取得する代わりに、「partition by」句なしでウィンドウ関数を使用できます。
使用している場合:
count(*)
グループの数を取得するには、以下を使用できます。
sum(count(*)) over ()
合計数を取得します。
例えば:
select Grade, 100. * count(*) / sum(count(*)) over ()
from table
group by Grade;
私の経験ではより高速になる傾向がありますが、内部で一時テーブルを使用する場合があると思います( "set statistics io on"で実行しているときに "Worktable"を見たことがあります)。
編集: 私のクエリ例があなたが探しているものであるかどうかはわかりません、私はウィンドウ関数がどのように機能するかを単に示していました。
tempdb
作業テーブルであるスプールを使用します。論理読み取りは高いように見えますが、通常とは異なる方法でカウントされます
COUNT(*) OVER ()
クエリ内のは、まったく関係のない数値(具体的には、グループ化された結果セットの行数)を返します。SUM(COUNT(*)) OVER ()
代わりに使用する必要があります。
成績の合計を計算する必要がありますSQL 2005の場合、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
成績フィールドでグループ化する必要があります。このクエリは、ほとんどすべてのデータベースで探しているものを提供します。
Select Grade, CountofGrade / sum(CountofGrade) *100
from
(
Select Grade, Count(*) as CountofGrade
From Grades
Group By Grade) as sub
Group by Grade
使用しているシステムを指定する必要があります。
以下はうまくいくはずです
ID - Key
Grade - A,B,C,D...
編集:を移動し* 100
て追加し、1.0
整数除算を行わないようにしました
Select
Grade, Count(ID) * 100.0 / ((Select Count(ID) From MyTable) * 1.0)
From MyTable
Group By Grade
IBM Informix Dynamic Server 11.50.FC3を使用してテストしましたが、これは一般的な解決策だと思います。次のクエリ:
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;
水平線の下に表示されるテストデータについて、次の出力が得られます。ROUND
関数は、DBMS固有のかもしれないが、残りは(おそらく)ではありません。(100から100.0に変更して、非整数-DECIMAL、NUMERIC-算術を使用して計算が行われるようにしました。コメントを参照してください。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');
SQLサーバーのどのバージョンでも、次のようにすべてのグレードの合計に変数を使用できます。
declare @countOfAll decimal(18, 4)
select @countOfAll = COUNT(*) from Grades
select
Grade, COUNT(*) / @countOfAll * 100
from Grades
group by Grade
fromクエリで副選択を使用できます(テストされておらず、どちらが速いかわかりません)。
SELECT Grade, COUNT(*) / TotalRows
FROM (SELECT Grade, COUNT(*) As TotalRows
FROM myTable) Grades
GROUP BY Grade, TotalRows
または
SELECT Grade, SUM(PartialCount)
FROM (SELECT Grade, 1/COUNT(*) AS PartialCount
FROM myTable) Grades
GROUP BY Grade
または
SELECT Grade, GradeCount / SUM(GradeCount)
FROM (SELECT Grade, COUNT(*) As GradeCount
FROM myTable
GROUP BY Grade) Grades
ストアドプロシージャを使用することもできます(Firebird構文の謝罪)。
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
これと同様の問題がありました。100ではなく1.0を掛けると正しい結果が得られるはずです。添付のサンプル画像をご覧ください
グレードを選択、(Count(Grade)* 1.0 /(MyTableからCount(*)を選択))をグレード別のMyTableグループからのスコアとして選択