SQLを書こう
実践編 - 合計残高試算表
なかじまゆうじ
はじめに
このスライドは、SQLの構文を覚えた新人に、
実際にSQL文を書くときの考え方を説明するた
めに作成したものです。
標準SQLを想定していますが、一部、SQL
Serverに依存している部分があります。
「合計残高試算表」ってなに?
会計の帳票の1つです。
仕訳帳を勘定科目ごとに貸借金額を合計した
ものです。
「借方残高」「借方合計」「勘定科目名」
「貸方合計」「貸方残高」の5列で構成され
ます。
「合計残高試算表」ってなに?
「借方合計」には、勘定科目ごとの借方の合
計金額が入ります。
「貸方合計」には、勘定科目ごとの貸方の合
計金額が入ります。
「合計残高試算表」ってなに?
「借方残高」と「貸方残高」には、勘定科目
ごとの残高が入ります。残高が借方にある
場合には「借方残高」、貸方にある場合に
は「貸方残高」に入ります。
「残高」ってなんだっけ?
借方金額と貸方金額の大きい方から小さい方
の金額を引いた残りです。
借方の方が大きければ借方に残高がある状態、
貸方の方が大きければ貸方に残高がある状
態です。
ということは
勘定科目ごとの借方合計金額と貸方合計金額が
あれば(これが合計試算表です)、残高の部分
は簡単に作れます。
つまり、こんな感じ。
select
(借方合計 - 貸方合計) as 借方残高,
勘定科目名,
(貸方合計 - 借方合計) as 貸方残高
from 合計試算表
小さい方の貸借に、
マイナス金額が出ちゃうじゃん。。。
小さい方は出ないようにしよう。
select
case
when 借方合計 > 貸方合計 then (借方合計 - 貸方合計)
else null
end as 借方残高,
勘定科目名,
case
when 借方合計 < 貸方合計 then (貸方合計 - 借方合計)
else null
end as 貸方残高
from 合計試算表
残高はできた。
あとは合計試算表をどう作るか。
「仕訳帳」ってどんな構造?
本来は「借方勘定科目と金額」「貸方勘定科
目と金額」が、それぞれ複数行存在するも
のです。
今回は、「勘定科目名」「貸借」「金額」の
3列のテーブルと考えます。
「勘定科目ごとの合計金額」なら
select
勘定科目名,
sum(金額) as 合計金額
from 仕訳帳
group by 勘定科目名
「勘定科目ごとの借方合計金額」なら
select
勘定科目名,
sum(金額) as 借方合計
from 仕訳帳
where 貸借 = '借方'
group by 勘定科目名
「勘定科目ごとの貸方合計金額」なら
select
勘定科目名,
sum(金額) as 貸方合計
from 仕訳帳
where 貸借 = '貸方'
group by 勘定科目名
両方繋ぐと?
select 借方.借方合計, 借方.勘定科目名, 貸方.貸方合計
from (
select 勘定科目名, sum(金額) as 借方合計
from 仕訳帳
where 貸借 = '借方'
group by 勘定科目名
) as 借方
inner join (
select 勘定科目名, sum(金額) as 貸方合計
from 仕訳帳
where 貸借 = '貸方'
group by 勘定科目名
) as 貸方
on 貸方.勘定科目名 = 借方.勘定科目名
片方にしかない勘定科目がなくなる!
left outerだと?
select 借方.借方合計, 借方.勘定科目名, 貸方.貸方合計
from (
select 勘定科目名, sum(金額) as 借方合計
from 仕訳帳
where 貸借 = '借方'
group by 勘定科目名
) as 借方
left outer join (
select 勘定科目名, sum(金額) as 貸方合計
from 仕訳帳
where 貸借 = '貸方'
group by 勘定科目名
) as 貸方
on 貸方.勘定科目名 = 借方.勘定科目名
貸方にしかない科目がなくなる!
full outerだと?
select 借方.借方合計, 借方.勘定科目名, 貸方.貸方合計
from (
select 勘定科目名, sum(金額) as 借方合計
from 仕訳帳
where 貸借 = '借方'
group by 勘定科目名
) as 借方
full outer join (
select 勘定科目名, sum(金額) as 貸方合計
from 仕訳帳
where 貸借 = '貸方'
group by 勘定科目名
) as 貸方
on 貸方.勘定科目名 = 借方.勘定科目名
貸方にしかない勘定科目の
勘定科目名が出ない!
最終的に、こんな感じ。
select 借方.借方合計, coalesce(借方.勘定科目名, 貸方.勘定科目名) as 勘定科目名, 貸方.貸方合計
from (
select 勘定科目名, sum(金額) as 借方合計
from 仕訳帳
where 貸借 = '借方'
group by 勘定科目名
) as 借方
full outer join (
select 勘定科目名, sum(金額) as 貸方合計
from 仕訳帳
where 貸借 = '貸方'
group by 勘定科目名
) as 貸方
on 貸方.勘定科目名 = 借方.勘定科目名
仕訳帳がfromに2回も登場して、遅そう。
余談:遅いSQLの特徴
遅い(実行時間が長い)SQLになる条件はい
ろいろありますが、「from句に登場するテ
ーブル(実表)の数が多い」場合も遅くな
りがちです。
「実表」というのが曲者で、viewの場合はそ
の中に含まれる実表の数になります。
ということで、別解。
select
sum(case when 貸借 = '借方' then 金額 else 0 end) as 借方合計,
勘定科目名,
sum(case when 貸借 = '貸方' then 金額 else 0 end) as 貸方合計
from 仕訳帳
group by 勘定科目名
最終的に合計残高試算表は
select
case when 借方合計 > 貸方合計 then (借方合計 - 貸方合計) else null end as 借方残高,
借方合計,
勘定科目名,
貸方合計,
case when 借方合計 < 貸方合計 then (貸方合計 - 借方合計) else null end as 貸方残高
from (
select
sum(case when 貸借 = '借方' then 金額 else 0 end) as 借方合計,
勘定科目名,
sum(case when 貸借 = '貸方' then 金額 else 0 end) as 貸方合計
from 仕訳帳
group by 勘定科目名
) as 合計試算表
まとめ
joinのときは、行がなくならないように気を
つける。
事前に絞り込んでおかなくても、必要な情報
を1つの行に並べられれば、select句でなん
とかなる。
欲しいテーブルがなければ、作る。
from句に登場する実表の数に気をつける。
おしまい

SQLを書こう (実践編 - 合計残高試算表)