Access クエリで集計する方法 合計 件数 月別集計と数字が合わない原因

概要

この記事の結論
Accessの集計クエリは、クエリデザインで[集計]を表示し、まとめる項目を[グループ化]、数値を[合計]などに設定して作成します。正しい結果にするには、1行が伝票なのか明細なのかを決め、Nullや結合による重複を確認することが重要です。

この記事でわかること

  • 1行の意味と集計単位を先に決める
  • Count(*)は行数 Count(列)は非Null件数
  • 抽出後に集計し集計結果を条件で絞る
  • 結合前後の件数と金額を検算

この記事の主な内容

  1. 集計の単位と元データを決める
  2. 顧客別の合計をデザインビューで作る
  3. 件数 平均 Nullの扱いを理解する
  4. 期間条件と月別集計を設定する
  5. 集計が合わない原因を検算する
  6. レポートやグラフで集計結果を再利用する
  7. まとめ
  8. よくある質問

想定読了時間:約12分~16分


集計の単位と元データを決める

集計クエリを作る前に、「1行は何を表すか」「何ごとにまとめるか」「どの範囲を対象にするか」を決めます。同じ売上合計でも、伝票単位と明細単位が混在すると正しい数字になりません。

たとえば顧客別の売上なら、顧客IDでグループ化して売上金額を合計します。毎月の売上なら年月を集計キーにします。金額が正しく入っていることだけでなく、返品、取消、未確定のデータを含めるかも明確にしましょう。

データシートの集計行との違い

方法主な用途結果の使い方
データシートの集計行表示中の列の合計を手早く確認画面上の確認に便利
集計クエリ顧客別・月別などの集計表を作るレポートやグラフのデータソースに使う
クロス集計クエリ顧客を行、月を列にするなどの表縦横の比較に使う

画面下部に合計を表示する操作と、グループごとの結果を返すクエリは別です。本記事では、保存して帳票やグラフから再利用できる集計クエリを作ります。[S1][S2]

Accessの集計前に決める3つの条件を説明する図

検算できる小さなデータを用意する

T_売上に売上ID(数値型・長整数、主キー)、売上日(日付/時刻型)、顧客ID(短いテキスト)、売上金額(通貨型)を作ります。空欄はNullです。1行は1件の売上とし、以下は架空の説明用データです。

売上ID売上日顧客ID売上金額
12026/09/01C0110000
22026/09/10C0115000
32026/09/20C0220000
42026/09/30 15:30C02空欄
52026/10/01C015000

全期間ならC01は30,000円、C02は20,000円、合計50,000円です。9月だけならC01は25,000円、C02は20,000円、合計45,000円です。Nullの金額を含むID4も売上レコードとしては存在します。


顧客別の合計をデザインビューで作る

集計クエリでは、まとめる列と計算する列を区別します。顧客別合計なら顧客IDがまとめる列、売上金額が計算する列です。売上IDのような毎行異なる列までグループ化すると、顧客別にまとまらなくなります。

操作手順

1. [作成]→[クエリデザイン]を選び、T_売上を追加します。
2. 顧客IDと売上金額をダブルクリックして下段のグリッドへ追加します。
3. デザイン関連のタブでΣの[集計]をクリックし、グリッドに集計行を表示します。
4. 顧客IDは[グループ化]、売上金額は[合計]に設定します。
5. 顧客IDの並べ替えを昇順にし、データシートビューで2行になるか確認します。
6. Q_顧客別売上という名前で保存します。

グリッドの行顧客ID列売上金額列
フィールド顧客ID売上金額
集計グループ化合計
並べ替え昇順指定なし
表示オンオン

表示列名を分かりやすくするなら、金額列のフィールド行を「売上合計: 売上金額」とします。SQLビューでは次のように表せます。これは全期間の集計なので、結果はC01が30,000円、C02が20,000円です。

SELECT [顧客ID], Sum([売上金額]) AS [売上合計]
FROM [T_売上]
GROUP BY [顧客ID]
ORDER BY [顧客ID];

グループに含める列を増やすと結果も変わる

顧客IDに加えて売上日をグループ化すると、顧客ごと・日付ごとの結果になります。売上IDまで加えれば、ほぼ明細と同じ粒度に戻ります。「集計しているのに行数が減らない」場合は、計算式よりグループ化した列を確認してください。

顧客名を表示したい場合、名前の表記揺れによって同じIDが別行になることもあります。安定した顧客IDで先に集計し、一意な顧客マスタから表示名を付ける方法が分かりやすいでしょう。

Accessのグループ化と合計の設定を説明する図

件数 平均 Nullの扱いを理解する

件数はCount、平均はAvg、最小値はMin、最大値はMaxを使います。ただし、Nullの扱いが結果に影響します。特に「件数」という表示だけでは、行数か、金額が入力された行数か分かりません。[S1][S3]

Count(*)とCount(列)の違い

Count(*)は行数を数えます。Count([売上金額])は売上金額がNullでない行を数えるため、空欄の金額は対象外です。0円はNullではないので、Count([売上金額])でも数えます。

SELECT [顧客ID],
       Count(*) AS [売上件数],
       Count([売上金額]) AS [金額入力件数],
       Sum([売上金額]) AS [売上合計],
       Avg([売上金額]) AS [平均金額]
FROM [T_売上]
GROUP BY [顧客ID];

顧客ID売上件数金額入力件数売上合計平均金額
C01333000010000
C02212000020000

C02の平均は、入力されている20,000円だけを対象とするため20,000円です。2行で割った10,000円ではありません。この違いを理解せず平均を使うと、未入力が多いグループを誤って評価してしまいます。

AccessのCountとNullの関係を説明する図

Nullをゼロへ変える前に意味を決める

Avg(Nz([売上金額],0))なら、未入力を0として計算するため、C02の平均は10,000円になります。計算できることと、業務上正しいことは別です。未確定や入力漏れならゼロにせず、金額未入力件数を別に出す方が状況を説明できます。

また、金額がすべてNullのグループではSumがNullになる場合があります。Nz(Sum([売上金額]),0)は表示を0にできますが、そもそも対象行がなくグループが存在しない場合には、新しいグループ行を作りません。0件の顧客も出すには顧客マスタを起点とする設計が必要です。

平均の平均に注意する

2件の平均が10,000円、8件の平均が20,000円なら、全10件の平均は18,000円です。2つの平均を単純に平均した15,000円ではありません。全体の平均は元の金額から計算するか、合計と対応する件数を使って重み付けします。


期間条件と月別集計を設定する

期間で元レコードを絞ってから集計し、必要に応じて集計結果をさらに絞ります。SQLでは前者がWHERE、後者がHAVINGです。この順序を意識すると、「売上がある行の条件」と「顧客別合計の条件」を混同しにくくなります。[S4][S5]

9月の売上合計が2万円以上の顧客

SELECT [顧客ID], Sum([売上金額]) AS [売上合計]
FROM [T_売上]
WHERE [売上日] >= DateSerial(2026,9,1)
  AND [売上日] < DateSerial(2026,10,1)
GROUP BY [顧客ID]
HAVING Sum([売上金額]) >= 20000
ORDER BY [顧客ID];

結果はC01が25,000円、C02が20,000円です。WHEREに「売上金額>=20000」を書くと、1件ごとの金額で先に絞るため、10,000円と15,000円を持つC01が除外されます。合計2万円以上を調べたい場合とは意味が異なります。

デザインビューでは、売上日を追加し、集計行を[Where条件]、抽出条件を9月の範囲とします。合計する金額列の抽出条件に>=20000を指定すると、合計値に対する条件になります。SQLビューでもWHEREとHAVINGの位置を確認してください。

AccessのWHEREとHAVINGの順序を説明する図

年月ごとの合計を作る

月別集計では年を区別します。Month([売上日])だけでまとめると、複数年の同じ月が合算されます。月初日の日付を作ってグループ化すると、年をまたいでも順番を保ちやすくなります。

SELECT DateSerial(Year([売上日]),Month([売上日]),1)
       AS [売上月],
       Sum([売上金額]) AS [月売上]
FROM [T_売上]
WHERE [売上日] Is Not Null
GROUP BY DateSerial(Year([売上日]),Month([売上日]),1)
ORDER BY DateSerial(Year([売上日]),Month([売上日]),1);

このサンプルでは2026年9月45,000円、10月5,000円の2行になります。日付のない売上はWHEREで除外しているため、日付未入力の件数は別に確認します。除外したことを忘れると、全体合計との差を説明できなくなります。

表示書式だけをyyyy/mmに変えると、月初日の値を保ったまま年月表示にできます。一方、「9月」だけの文字列は年が分からず並べ替えも扱いづらくなるので、計算用のキーと表示用の文字を区別しましょう。

Accessの年を区別する月別集計を説明する図

集計が合わない原因を検算する

集計値が多い場合、結合で元レコードが増えていないかを最初に調べます。Sum関数が誤っているのではなく、同じ金額を複数回合計しているケースがあります。

伝票合計と明細を結合した場合

1件の伝票に合計30,000円があり、明細が3行あるとします。伝票と明細を結合すると、伝票合計30,000円が3行に繰り返されます。この列をSumすると90,000円になり、正しい30,000円の3倍になります。

集計したいもの基準にするデータ考え方
伝票単位の売上伝票テーブル伝票合計を1伝票1回だけ集計
商品別の売上明細テーブル明細金額を商品ごとに集計
入金と売上の比較それぞれを同じ単位へ集計集計後に顧客等で結合

重複している金額をDistinctで消す方法は避けます。別の伝票でも同額になることがあり、正しい売上まで除いてしまう可能性があるからです。どのキーで1件を識別するかを確認し、各テーブルを必要な単位まで集計してから結合します。

Accessの結合による二重計上を防ぐ方法を説明する図

症状別の確認表

症状確認すること対処の方向
合計が倍・数倍結合後のキー別件数マスタ一意性と明細の粒度を修正
月末の売上がない日付に時刻があるか翌月初日未満の条件へ
件数が少ないCountの対象列がNullか行数ならCount(*)を使う
顧客が複数行になる名前や日付もグループ化しているか集計キーを目的に合わせる
金額を合計できない列が短いテキストになっていないか元データと取込時の型を確認
集計フィールドに含まれていないエラー表示列の集計方法グループ化か集計関数を指定

文字列の金額をその場で強制変換する前に、桁区切り、通貨記号、空文字、不正値を検査します。データ型が違うまま式で無理に吸収すると、ある月だけ失敗する処理になりやすくなります。

件数と金額の両方を照合する

サンプルの9月は4行、金額入力は3行、合計45,000円です。件数と合計をセットで確認すると、Nullの行が落ちたのか、金額が重複したのかを切り分けやすくなります。代表顧客の明細まで戻って説明できることが大切です。

日付・顧客・金額の条件を記録し、元データの総計、集計後の総計、対象外の扱いを照合します。差があった場合、数字を合わせるために条件を変更するのではなく、どの行が増減したかを特定してください。

集計のずれが解消できない場合は、クエリのSQL、テーブル構造、正しいはずの数値と根拠を整理して相談しましょう。Accessの教科書では既存Accessの集計処理やデータ構成の調査・改修を支援しています。


レポートやグラフで集計結果を再利用する

検算した集計クエリは、レポートやグラフのデータソースとして利用できます。帳票ごとに別の式を書くより、対象条件と計算ルールをそろえやすくなります。ただし、利用先で再集計する場合は元クエリの粒度を確認します。

用途に応じて形を選ぶ

顧客別合計を印刷するなら136「レポートの作り方」、月別売上を可視化するなら137「グラフの作り方」につなげます。グラフの値にカウントを選ぶと売上額ではなく行数になるため、クエリ側と表示側の両方を確認してください。

顧客を行、月を列に並べる比較表にはクロス集計が候補です。ただし月の増減で列名が変わるため、固定レイアウトのレポートで使う場合は列見出しの固定や対象期間を設計します。まず通常の集計クエリで数字を確認してから形式を変えると安心です。[S6]

運用時の確認チェック

1. 1行の意味、集計キー、対象期間を説明できるようにします。
2. Count(*)とCount(列)、Nullとゼロの扱いを明記します。
3. 元データと結果の件数・金額を照合します。
4. 結合先のキーが一意か、結合で行が増えないか確認します。
5. データ0件、全金額Null、年またぎ、マスタ未登録を試します。

Accessの集計結果の検算チェックを説明する図

処理が遅い場合は、結合キーや条件列のインデックス、データ量、ネットワーク上の配置などを順に調べます。データ量が大きい既存システムでは、Accessの画面を残し、集計をSQL Server側で処理する方法も選択肢です。まず遅い箇所を特定してから構成を判断しましょう。


まとめ

集計クエリは、グループ化する列と合計する列を選んで作成できます。実務ではCountとNull、WHEREとHAVING、年を含む月別キー、結合後の重複まで確認することが重要です。サンプルの件数と45,000円の9月合計を照合できたら、自社の定義へ置き換えて活用してください。

よくある質問

クエリをデザインビューで開き、Σの集計コマンドを選びます。データシート下部に出す集計行とは操作と目的が異なります。

売上IDや売上日など、細かい単位の列までグループ化していないか確認します。顧客別なら安定した顧客IDを基本キーにします。

異なります。前者は行数、後者は売上金額がNullでない行の数です。0円はNullではないため後者でも数えます。

Nullは通常、集計対象の値から除かれます。全件Nullの場合と数値0の合計は区別が必要です。必要に応じて未入力件数も表示します。

WHEREはグループ化前の元レコード、HAVINGはグループ化後の集計結果を絞ります。対象期間はWHERE、合計2万円以上などはHAVINGが基本です。

Monthだけでなく年を含むキーを使います。月初日をDateSerialで作って集計すると、年を含む日付として並べられます。

結合で同じ伝票金額が複数行に繰り返されていないか確認します。伝票と明細などの粒度を合わせ、必要に応じて先に集計してから結合します。

集計結果は一般に元データの個々の行へ対応しないため直接更新には向きません。明細の入力フォームなどで元データを修正し、再集計して結果を確認します。

Accessの集計値のずれと処理速度を相談する

本文の確認手順を試しても原因を絞れない場合は、元データの定義、使っているクエリ、期待する結果、実際の症状を整理してご相談ください。


参考情報

[S1] Microsoft クエリを使用してデータを集計する
https://support.microsoft.com/ja-jp/access/sum-data-by-using-a-query

[S2] Microsoft クエリを使用してデータをカウントする
https://support.microsoft.com/ja-jp/access/count-data-by-using-a-query

[S3] Microsoft Count関数
https://learn.microsoft.com/ja-jp/office/vba/access/concepts/criteria-expressions/count-function-microsoft-access-sql

[S4] Microsoft HAVING句
https://learn.microsoft.com/ja-jp/office/vba/access/concepts/structured-query-language/having-clause-microsoft-access-sql

[S5] Microsoft GROUP BY句
https://learn.microsoft.com/ja-jp/office/vba/access/concepts/structured-query-language/group-by-clause-microsoft-access-sql

[S6] Microsoft クロス集計クエリを使用して集計データを読みやすくする
https://support.microsoft.com/ja-jp/access/make-summary-data-easier-to-read-by-using-a-crosstab-query

関連記事

Accessのインデックスとは 設定と効果|Accessの教科書

Access レポートの作り方と失敗しない確認手順|Accessの教科書

Accessでグラフを作る方法と失敗しない確認手順|Accessの教科書

Access 不一致クエリで差分を求める方法と失敗しない確認手順

Access クエリの作成方法と失敗しない確認手順|Accessの教科書

TOP