shikakuホームへ
経営情報システム / データベースと開発デー
データベースと開発 2/5 / 約5分

SQLとACID — 絞ってから集めるか、集めてから絞るか

「店舗ごとの売上合計を出して、1,000万円を超えた店舗だけ表示したい」——この「絞り込み」、合計を出すの行への条件と、合計を出したのグループへの条件は、SQLでは別の言葉です。ここを混ぜるのが定番の的。

そしてもう1つの主役が、銀行振込を支える4つの約束(ACID)です。

この5分の問い

WHEREとHAVINGはどう使い分け、ACID特性は何を保証しているのでしょうか。

直感でつかむ

WHEREは集約前の行、HAVINGは集約後のグループに効きます

WHEREグループ分け(集約)の前に、1行1行を絞り込む条件——「今月の売上データだけ」。HAVINGGROUP BYで集約した後に、グループ(集計結果)を絞り込む条件——「合計が1,000万円を超えた店舗だけ」。絞ってから集めるのがWHERE、集めてから絞るのがHAVINGです。

ACIDは銀行振込で考えます——A口座から引き落とし、B口座へ入金という2つの操作は、原子性(全部やるか全部やらないか——片方だけは許さない)・一貫性(残高の整合が崩れない)・独立性(他の処理の途中経過が混ざらない)・耐久性(完了した取引は障害でも消えない)の4つの約束で守られています。

SQLの合言葉WHERE=集約前の行・HAVING=集約後のグループ——ACID=原子性・一貫性・独立性・耐久性
厳密に見る

命令の4分類と、分離レベルの両端も持ち帰ります

SQLの命令は4分類——DML(データ操作:SELECT・INSERT・UPDATE・DELETE)・DDL(定義:CREATE・ALTER・DROP・TRUNCATE)・DCL(権限:GRANT・REVOKE)・TCL(トランザクション制御:COMMIT・ROLLBACK・SAVEPOINT)。表の結合(JOIN)にはINNER・LEFT/RIGHT/FULL OUTER・CROSSがあります。

独立性の強さはトランザクション分離レベルで調整します——最弱のREAD UNCOMMITTEDでは他の処理の未確定データまで読めてしまい(ダーティリード)、反復不能読み取り・ファントムリードも起きうる。最強のSERIALIZABLEは3つの異常を全て防ぐ代わりに、同時実行の性能が落ちます。「強いほど安全、弱いほど速い」のトレードオフです。

結論が反転する分かれ目
WHERE
集約前——行を絞る
GROUP BYの前に1行ずつ判定(今月のデータだけ)
HAVING
集約後——グループを絞る
集計結果に条件(合計1,000万円超の店舗だけ)
分かれ目 集約の前か後か。集計値への条件をWHEREで書かせる肢が定番です。
ここで間違える

WHERE/HAVINGの取り違えと、TRUNCATEの分類が的です

定番の誤り肢は「集約後の条件をWHEREで書く」——集計結果(SUMやCOUNT)への条件はHAVINGです。逆に「集約前の行の絞り込みにHAVINGを使う」も誤り。集約の前か後かだけで判定できます。

命令の分類ではTRUNCATEが的——表の全行を消すので DELETE(DML)の仲間に見えますが、分類はDDLです。分離レベルは「SERIALIZABLEはダーティリードが発生する」型の入れ替え——最強レベルは全て防ぐ、が正です。

実務では

診断士がSQLを書く場面は多くありませんが、BIツールやPOS分析のフィルタ設計でWHERE/HAVINGの区別はそのまま生きます——「単価500円以上の商品だけ集計」(集約前=WHERE相当)と「合計が100万円超のカテゴリだけ表示」(集約後=HAVING相当)は別のフィルタです。ACIDは会計システムの信頼性を顧問先に説明する語彙——「仕訳が中途半端に残らないのは原子性のおかげ」です。

確かめる — 予想してから答え合わせ
この5分のまとめ

冒頭の問いに答えます。WHEREは集約前の行の絞り込み、HAVINGは集約後のグループの絞り込み——「絞ってから集めるか、集めてから絞るか」です。ACIDは原子性(全部か無か)・一貫性・独立性・耐久性の4つの約束で取引を守り、独立性の強さは分離レベル(最弱READ UNCOMMITTED〜最強SERIALIZABLE)で調整します。次は、システムをどう作り進めるか——開発モデルへ。