[解決済み] postgresqlでクエリから最小値、中央値、最大値を取得するにはどうすればよいですか?
質問
私は、1つの列が月であるクエリを書きました。そこから、最小の月、最大の月、中央の月を取得する必要があります。以下は私のクエリです。
select ext.employee,
pl.fromdate,
ext.FULL_INC as full_inc,
prevExt.FULL_INC as prevInc,
(extract(year from age (pl.fromdate))*12 +extract(month from age (pl.fromdate))) as month,
case
when prevExt.FULL_INC is not null then (ext.FULL_INC -coalesce(prevExt.FULL_INC,0))
else 0
end as difference,
(case when prevExt.FULL_INC is not null then (ext.FULL_INC - prevExt.FULL_INC) / prevExt.FULL_INC*100 else 0 end) as percent
from pl_payroll pl
inner join pl_extpayfile ext
on pl.cid = ext.payrollid
and ext.FULL_INC is not null
left outer join pl_extpayfile prevExt
on prevExt.employee = ext.employee
and prevExt.cid = (select max (cid) from pl_extpayfile
where employee = prevExt.employee
and payrollid = (
select max(p.cid)
from pl_extpayfile,
pl_payroll p
where p.cid = payrollid
and pl_extpayfile.employee = prevExt.employee
and p.fromdate < pl.fromdate
))
and coalesce(prevExt.FULL_INC, 0) > 0
where ext.employee = 17
and (exists (
select employee
from pl_extpayfile preext
where preext.employee = ext.employee
and preext.FULL_INC <> ext.FULL_INC
and payrollid in (
select cid
from pl_payroll
where cid = (
select max(p.cid)
from pl_extpayfile,
pl_payroll p
where p.cid = payrollid
and pl_extpayfile.employee = preext.employee
and p.fromdate < pl.fromdate
)
)
)
or not exists (
select employee
from pl_extpayfile fext,
pl_payroll p
where fext.employee = ext.employee
and p.cid = fext.payrollid
and p.fromdate < pl.fromdate
and fext.FULL_INC > 0
)
)
order by employee,
ext.payrollid desc
もしそれが不可能なら、最大月と最小月を取得することは可能でしょうか?
どのように解決するのですか?
という名前の集約関数が必要です。
min
と
max
. PostgreSQLのドキュメントとチュートリアルを参照してください。
- http://www.postgresql.org/docs/current/static/tutorial-agg.html
- http://www.postgresql.org/docs/current/static/functions-aggregate.html
PostgreSQLには組み込みのmedianはありませんが、実装され、wikiに寄稿されています。
http://wiki.postgresql.org/wiki/Aggregate_Median
と同じように使われます。
min
と
max
を読み込むと PL/PgSQLで書かれているため、かなり遅くなりますが、C言語版もありますので、速度が重要な場合はそちらを適用することもできます。
アップデイト コメント後
統計的な集計を個々の結果と一緒に表示したいようですね。にないカラムを参照することができないので、単純な集約関数ではこれを行うことはできません。
GROUP BY
を結果一覧に表示します。
サブクエリから統計情報を取得するか、ウィンドウ関数としてアグリゲートを使用する必要があります。
ダミーデータが与えられた
CREATE TABLE dummystats ( depname text, empno integer, salary integer );
INSERT INTO dummystats(depname,empno,salary) VALUES
('develop',11,5200),
('develop',7,4200),
('personell',2,5555),
('mgmt',1,9999999);
を追加し、さらに PG wikiにある中央値集計表 :
普通の集合体でもできます。
regress=# SELECT min(salary), max(salary), median(salary) FROM dummystats;
min | max | median
------+---------+----------------------
4200 | 9999999 | 5377.5000000000000000
(1 row)
が、これは違う。
regress=# SELECT depname, empno, min(salary), max(salary), median(salary)
regress-# FROM dummystats;
ERROR: column "dummystats.depname" must appear in the GROUP BY clause or be used in an aggregate function
というのも、平均値を個々の値と一緒に表示するのは、集計モデルとして意味がないからです。グループを表示することはできます。
regress=# SELECT depname, min(salary), max(salary), median(salary)
regress-# FROM dummystats GROUP BY depname;
depname | min | max | median
-----------+---------+---------+-----------------------
personell | 5555 | 5555 | 5555.0000000000000000
develop | 4200 | 5200 | 4700.0000000000000000
mgmt | 9999999 | 9999999 | 9999999.000000000000
(3 rows)
... しかし、あなたは個々の値が欲しいようですね。その場合は ウィンドウ これはPostgreSQL 8.4で追加された機能です。
regress=# SELECT depname, empno,
min(salary) OVER (),
max(salary) OVER (),
median(salary) OVER ()
FROM dummystats;
depname | empno | min | max | median
-----------+-------+------+---------+-----------------------
develop | 11 | 4200 | 9999999 | 5377.5000000000000000
develop | 7 | 4200 | 9999999 | 5377.5000000000000000
personell | 2 | 4200 | 9999999 | 5377.5000000000000000
mgmt | 1 | 4200 | 9999999 | 5377.5000000000000000
(4 rows)
こちらもご覧ください。
関連
-
[解決済み] PostgreSQLのCASE ... 複数条件付きEND
-
[解決済み] PostgreSQL コマンドラインユーティリティ: psql を終了する方法
-
[解決済み] PostgreSQLのユーザーパスワードを変更する方法を教えてください。
-
[解決済み] PostgreSQLからのPL/pgSQL出力をCSVファイルに保存する
-
[解決済み] PostgreSQLデータベースにアクティブな接続がある場合、そのデータベースを削除する方法は?
-
[解決済み] Postgresqlで「大文字小文字を区別しない」クエリを作成する方法は?
-
[解決済み】Mac OS XでPostgreSQLサーバーを起動するには?
-
[解決済み】Postgresに一括挿入を行う最速の方法は何ですか?
-
[解決済み】PostgreSQLでUTCの現在時刻をデフォルト値として使用する。
-
[解決済み】PostgreSQLでUPSERT(MERGE、INSERT ... ON DUPLICATE UPDATE)する方法とは?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Postgresql Select rows where column = array (列 = 配列)
-
[解決済み] Rails 4でPostgreSQLサーバーのデフォルトのユーザー名/パスワードは何ですか?
-
[解決済み] PostgreSQLのCASE ... 複数条件付きEND
-
[解決済み] postgres がサーバー構成の場所を知らない
-
[解決済み] Ubuntu 18.04でPostgreSQLを再起動する方法
-
[解決済み] PostgreSQL の 'NOT IN' とサブクエリ
-
[解決済み】psql: FATAL: ユーザー "postgres" の Ident 認証に失敗しました。
-
[解決済み】postgreSQL で既存のテーブルに対して "create table" SQL 文を生成する方法
-
[解決済み】Postgresの手動によるシーケンスの変更
-
[解決済み] [Solved] "on delete cascade "制約を追加する方法は?