SQL:ウィンドウ関数(OVER句)でランキング・累計を計算する

データ分析やレポート作成では、「順位付け」「累計」 のような集計処理がよく登場します。
従来はサブクエリや自己結合を使う必要がありましたが、SQLの ウィンドウ関数(OVER句) を使えば簡潔に記述できます。
この記事では、代表的な使い方と主要DBMSごとの対応状況をサンプル付きで解説します。


🧠 ウィンドウ関数とは?

ウィンドウ関数とは、集計関数に対して「範囲(ウィンドウ)」を指定できる機能です。
通常の SUM()AVG() はグループ全体を集計しますが、OVER() を使うことで「行単位の集計」も可能になります。

🔸 基本構文

関数名(列名) OVER (PARTITION BY 列名 ORDER BY 列名)
役割
PARTITION BYグループを分ける(省略可)
ORDER BY並び順を指定
ROWS BETWEEN ~範囲を細かく指定(任意)

🏅 ランキングを求める

商品の売上データを例に、売上額で順位をつけます。

📘 サンプルテーブル:sales

productcategoryamount
A飲料300
B飲料500
C食品400
D食品200
E食品700

📗 SQL例

📊 実行結果

categoryproductamountrank
飲料B5001
飲料A3002
食品E7001
食品C4002
食品D2003

ポイント

  • 同じカテゴリ内で順位を付与 (PARTITION BY category)

  • 売上が高い順に並び替え (ORDER BY amount DESC)

  • RANK() は同順位がある場合にスキップ(例:1位,1位,3位)


🔢 累計を求める

カテゴリ別に売上の累計を出してみましょう。

📗 SQL例

📊 結果

categoryproductamountrunning_total
飲料B500500
飲料A300800
食品E700700
食品C4001100
食品D2001300

ポイント

  • SUM()OVER() を組み合わせることで行ごとの累積が可能

  • ORDER BY により順序を指定できる

  • PARTITION BY を省略すると全体累計に


🧮 他の代表的なウィンドウ関数

関数説明
ROW_NUMBER()連番(重複なし)を付与
RANK()同順位があるとスキップ(例:1,1,3)
DENSE_RANK()同順位があっても連続(例:1,1,2)
NTILE(n)n等分にグループ分け(例:四分位)
LAG(col, n)n行前の値を取得
LEAD(col, n)n行後の値を取得
SUM(), AVG(), MAX(), MIN()累計・平均などの集計を行単位で

💡 応用例:前回比を計算する

前回の売上からの増減を求めたい場合は LAG() 関数を使用します。



FROM sales;
categoryproductamountprev_amountdiff
飲料B500NULLNULL
飲料A300500-200
食品E700NULLNULL
食品C400700-300
食品D200400-200

🧭 DBMS別のウィンドウ関数対応表

DBMS対応状況対応バージョン備考
Oracle Database◎ 完全対応8i 以降ウィンドウ関数発祥の実装。機能最も豊富
PostgreSQL◎ 完全対応8.4 以降PARTITION, ORDER, RANGE句など全対応
MySQL○ 部分対応8.0 以降8.0から正式対応(それ以前は非対応)
SQL Server◎ 完全対応2012 以降LAG/LEADなどもサポート
SQLite○ 部分対応3.25 以降一部関数は制限あり(NTILEなど)
MariaDB△ 限定対応10.2 以降SUMなどは対応、LAG/LEADは制限あり
IBM Db2◎ 完全対応9.7 以降分析関数として強力なサポートあり
Snowflake / BigQuery◎ 完全対応最新クラウドDWH系でもネイティブ対応

補足

  • 旧バージョンのMySQL(5.x系)ではウィンドウ関数が非対応のため、サブクエリで代替が必要。

  • PostgreSQLとOracleはROWS BETWEENなどの範囲指定も細かく制御可能。

  • BigQueryはOVER()句のほかQUALIFY句でフィルタリングが可能。


🔍 まとめ

観点内容
機能グループ単位での行ごとの集計・順位付け
主な用途累計・ランキング・前回比・順位比較
メリットサブクエリ不要・可読性向上・パフォーマンス改善
対応DBOracle, PostgreSQL, SQL Server, MySQL 8+, BigQueryなど

ウィンドウ関数は、分析SQLの最重要機能といっても過言ではありません。
集計・比較・順位などを自在に扱えるようになれば、レポート作成の幅が大きく広がります。

🧩 Oracle「ORA-01000: 最大オープン・カーソル数を超えました」対処手順

🔍 エラー概要

項目内容
エラーコードORA-01000
メッセージ最大オープン・カーソル数を超えました
発生原因開いたカーソルをクローズせずに処理を繰り返した結果、open_cursors の上限に達した
対応優先度高(アプリケーション修正・設定見直しが必要)

🧠 原因と仕組み

Oracle では、SQL 実行時に「カーソル」という内部ハンドルを使用して SQL 文を管理します。
アプリケーションが PreparedStatementResultSet を閉じずに再利用し続けると、未解放のカーソルが蓄積し、open_cursors パラメータで設定された上限値を超えた時点で ORA-01000 が発生します。


🧩 よくある原因パターン

原因詳細
JDBCのクローズ漏れResultSet や Statement を close() していない
ループ内で毎回 SQL を preparePreparedStatement を都度生成して再利用していない
コネクションプールの設定ミスコネクションが正しく解放されず、カーソルが残存
長時間実行バッチ同一セッションで大量SQLを連続実行してカーソルが累積
外部ライブラリのバグORM(MyBatis、Hibernate等)でのカーソル管理不具合

🧭 対処法(順序付き)

手順対処内容
アプリケーションコードを点検(ResultSet, Statement, Connection を確実に close)
try-with-resources 構文を使用して自動クローズ化(Java7以降推奨)
open_cursors パラメータ値を確認(show parameter open_cursors;)
必要に応じて上限を引き上げ(例:ALTER SYSTEM SET open_cursors = 1000 SCOPE=BOTH;)
v$open_cursor ビューで調査(どのSQLが残っているか確認)

🔧 調査SQL例 


💡 Javaでの修正例(try-with-resources構文)

✅ これにより、ResultSetPreparedStatementConnection が自動的にクローズされます。


⚙️ open_cursors の推奨設定値

システム規模推奨値備考
開発・検証環境300〜500検証負荷に応じて柔軟に設定
小〜中規模業務システム500〜1000通常アプリでは十分
大規模バッチ・Webサービス1000〜2000コネクションプール利用時に余裕をもたせる

🚨 注意点

  • open_cursors の値を単純に上げるだけでは根本解決になりません。
    アプリケーションでのクローズ処理修正が最優先

  • 定期的に v$open_cursor を監視することで、リークを早期発見できます。


✅ まとめ

観点内容
発生原因カーソルの未クローズや過剰生成
一時対応open_cursors の増加
根本対応コード修正(try-with-resources等)
チェック方法v$open_cursor / v$sesstat ビュー
再発防止コーディング規約・静的解析の導入

サイトの表示速度が遅い原因はこれ!画像の最適化で劇的改善

ブログなどの「サイトが重い」「表示に時間がかかる」と感じていませんか?
実は、その原因の1つに 画像の最適化不足 にあります。
どんなに優れたデザインや記事内容でも、ページの読み込みが遅いと離脱率が上がり、SEO評価も下がります。

この記事では、画像の最適化でブログの表示速度を劇的に改善する方法を、初心者でもできる手順で解説します。


🚨 表示速度が遅くなる主な原因

原因内容
画像サイズが大きい高解像度の画像をそのままアップロードしている
フォーマットが古いJPEGやPNGを多用し、WebPなどの軽量形式を使っていない
遅延読み込みが未設定ページ内の全画像を一度に読み込んでいる
キャッシュ未設定同じ画像を毎回サーバーから再取得している
CDN未使用地理的に離れたユーザーへの配信が遅れている

これらの要因を1つずつ対策すれば、PageSpeed Insightsのスコアが90点以上も狙えます。


💡 改善策①:画像を最適なサイズに圧縮する(WordPress対応)

ブログの表示速度改善において最も効果的なのが画像圧縮とリサイズです。
特にスマホ撮影画像やAI生成画像は数MBになることもあるため、1枚100KB以下を目指しましょう。


🔧 方法①:外部ツールで手動圧縮

ツール名特徴URL
TinyPNGPNG・JPEG対応。画質を保ちながら最大80%圧縮https://tinypng.com
Squoosh(Google製)WebP変換や画質比較ができるhttps://squoosh.app
ImageOptim(Mac)複数画像をドラッグ&ドロップでまとめて圧縮https://imageoptim.com

コツ:

  • 不要に大きい画像は横幅1200px程度にリサイズ

  • JPEGは写真向き、PNGは透過画像向き

  • 画質80%前後に設定すると肉眼ではほぼ違いなし


⚙️ 方法②:WordPressプラグインで自動圧縮

WordPressで作成されているサイトなら画像のアップロード時に自動圧縮してくれるプラグインを使えば、毎回手動で調整する必要がありません。
更新頻度の高いブログや、複数人で運営しているサイトに最適です。

プラグイン名主な機能無料範囲備考
EWWW Image Optimizer自動圧縮・WebP変換・既存画像一括最適化無制限(ローカル圧縮)高機能で安定
Imagify3段階圧縮(Normal/Aggressive/Ultra)+WebP対応月25MBまで無料操作が簡単
ShortPixelWebP+AVIF変換対応。画質維持率が高い月100枚まで無料自然な仕上がり
Smush一括最適化・遅延読み込み・CDN対応無料で5MB/画像定番&安心

🔹 EWWW Image Optimizer の設定例

  1. プラグインをインストールして有効化

  2. 「設定」→「EWWW Image Optimizer」を開く

  3. 「画像の自動最適化」を有効にする

  4. 「WebP変換」をONに

  5. 「既存画像を一括最適化」でライブラリ全体を処理

💡 ポイント: 初回は時間がかかりますが、次回以降は差分のみ圧縮されます。


💡 改善策②:WebP形式に変換する

WebPはGoogleが開発した次世代画像フォーマットで、JPEGより最大50%軽量化できます。
見た目の劣化もほとんどなく、主要ブラウザはすべて対応済みです。

プラグイン名主な機能
EWWW Image Optimizer自動WebP変換+フォールバック機能
Imagifyアップロード時に自動変換+圧縮
ShortPixelWebPとAVIFを両方生成

導入のメリット:

  • 軽量化によりLCP(Largest Contentful Paint)が改善

  • モバイルでの読み込み体感速度が向上

  • SEOスコアにも良い影響


💡 改善策③:遅延読み込み(Lazy Load)を有効化

ページを開いた瞬間に全画像を読み込む必要はありません。
**Lazy Load(レイジーロード)**を有効化すれば、
「ユーザーの画面に表示されたタイミングで読み込む」ようになります。

設定方法

  • WordPress 5.5以降:標準で loading="lazy" が自動付与

  • プラグイン利用例:

    • a3 Lazy Load

    • WP Rocket(有料)

    • Smush(画像圧縮+遅延読み込み対応)

💬 Lazy Loadを導入するだけで、初期ロード時間を30〜40%短縮できる場合があります。


💡 改善策④:CDNを活用する

CDN(Content Delivery Network)は、
世界中のサーバーに画像をキャッシュして、
ユーザーの位置に近いサーバーから配信します。

サービス名特徴
Cloudflare無料プランでも画像CDNが利用可能
Jetpack BoostWordPress専用CDN(Photon)対応
AWS CloudFront高速&安定。企業向けに最適

💡 改善策⑤:キャッシュプラグインを活用

画像最適化とあわせて、HTMLやCSSもキャッシュ化するとさらに高速化します。

プラグイン名特徴
LiteSpeed Cache画像圧縮・WebP・CDN・Lazy Load全部入りで高性能
WP Fastest Cacheシンプル操作で安定した効果を発揮
W3 Total Cache細かなチューニングが可能で上級者向け

🧠 Tip: LiteSpeedサーバー環境なら、LiteSpeed Cache一択でOKです。


🧪 改善効果の実例

項目最適化前最適化後改善率
トップページ画像10枚約6.2MB約1.8MB約70%削減
PageSpeed Insightsスコア63点91点+28ポイント改善
読み込み速度(3G環境)5.8秒2.1秒約3.7秒短縮

🧭 まとめ:画像最適化は“SEOとUX”の両方に効く!

  • 📉 無駄なデータ転送を削減 → 表示速度アップ

  • 📈 Core Web Vitals改善 → SEO評価向上

  • 😍 ユーザー離脱率を下げて滞在時間を増加

画像最適化=ブログの信頼性向上です。
一度設定しておけば、自動で軽量化される仕組みが完成します。
今日からあなたのブログも、「速くて軽い」理想のサイトへ変わります!