web-dev-qa-db-ja.com

割合を計算する個別の列が必要

次の表があります。

NAME
Alex
Bob 
Bob
Tim
Alex
Roger

以下を作成する必要があります。

 Name    Count Percentage
 Alex    2     33%
 Bob     2     33%
 Roger   1     16.6%
 Tim     1     16.6%

どこから始めればいいのかわかりません。カウントの最初のクエリは簡単です。

3
KingKongFrog

単一のSELECTで可能:

_SELECT name, count(*), to_char((count(*) * 100.0
                          / sum(count(*)) OVER ()), 'FM990.00" %"') AS percent
FROM   t
GROUP  BY 1
ORDER  BY 1;
_

count(*)関数の別の形式です で、count(<expression>)よりも少し高速です。すべての列が_NOT NULL_であると仮定すると、それ以外の場合は後者を使用する必要があります。

ウィンドウ集計関数sum(count(*)) OVER ()を実行して、同じSELECTの合計を取得できます。 SELECTのイベントのシーケンスを考えてみましょう:

これは、2つではなくone順次スキャンを使用し、通常、合計数のサブクエリを使用する場合より2倍高速です。

to_char() は出力をプレティッシュします。

_name  count  percent
-----------------------
Alex  2      33.33 %
Bob   2      33.33 %
Roger 1      16.67 %
Tim   1      16.67 %
_
9

これは Window Functions を使用する良い機会です:

create table names
(
  id serial,
  name text
);

insert into names (name)
values ('Alex'), ('Bob'), ('Bob'), ('Tim'), ('Alex'), ('Roger');

select distinct name, count(name) over (partition by name) as num,
       round( (count(name) over (partition by name)::numeric /
               count(name) over() ) * 100, 1) as pct
from names
order by num desc, name;

これにより、次のような出力が得られます。

NAME    NUM         PCT
Alex    2           33.3
Bob     2           33.3
Roger   1           16.7
Tim     1           16.7

少し異なるフォーマットが必要な場合は、丸めコードを微調整できます。 %pct列の値に連結することもできますが、最初にtextにキャストする必要があり、結果の列はtextになりますnumericに(これはあなたの場合には問題ないかもしれません)。

このクエリスタイルの大きな利点の1つは、テーブルがより複雑になり、列が増える場合でも、そのデータを処理し、クエリで返すことができ、さらに、次の理由により、カウントおよびパーセンテージデータにアクセスできることです。ウィンドウ関数スコープの仕組み。個別を削除すると、同じ名前でも行ごとに取得できます。

SQLフィドル

2
khampson
SELECT name,COUNT(*), ROUND(100.0*COUNT(name)/(SELECT 100.0* count(name)  FROM t),3) as percentage  
FROM t GROUP BY name

[〜#〜]フィドル[〜#〜]

1
Mihai

私は少し浮気しているようですが、これはあなたの結果を得るはずです:

with c as(
    select count(*) from "the_table"
), p as(
    select name,count(*) from "the_table" group by name
)
select
    p.name,
    p.count,
    ((p.count * 100) / c.count) percentage
from p,c
order by name
0
Lucas

1つの方法は、サブクエリを使用することです。

select 
    name, 
    count(*) as Count, 
    to_char(
      count(*)/(select cast(count(*) as decimal) from Table1)*100,'99.99'
    ) ||'%' as Percentage
from Table1
group by name

サンプルSQLフィドル

0
jpw
SELECT name, COUNT(name) as Count, (COUNT(name) / (SELECT COUNT(name) FROM table_name)) AS Percentage
FROM table_name GROUP BY name;
0
Arsen Y.M.