問題
req_date | req_qty | req_onhand_qty |
-----------+---------+----------------+
1994-07-01 | 100 | 100 |
1994-07-02 | 120 | 220 |
1994-07-03 | -150 | 70 |
1994-07-04 | 50 | 120 |
1994-07-05 | -35 | 85 |
fumikoの回答
SQL文
SELECT a1.req_date, sum(a2.req_qty) as req_onhand_qty
FROM InventoryAdjustments as a1,InventoryAdjustments as a2
WHERE a1.req_date >= a2.req_date
GROUP BY a1.req_date
考え方
- 2つのテーブルa1,a2を用意
- a1の日付>=a2の日付の条件で組み合わせる
(↓group byする前の状態。select a1.req_date,a2.req_qtyとしたとき)
a1date | a2qty
-----------+-------
1994-07-01 | 100
1994-07-02 | 100
1994-07-02 | 120
1994-07-03 | 100
1994-07-03 | 120
1994-07-03 | -150
1994-07-04 | 100
1994-07-04 | 120
1994-07-04 | -150
1994-07-04 | 50
1994-07-05 | 100
1994-07-05 | 120
1994-07-05 | -150
1994-07-05 | 50
1994-07-05 | -35
実行結果
req_date | req_onhand_qty
----------+----------------
1994-07-01 | 100
1994-07-02 | 220
1994-07-03 | 70
1994-07-04 | 120
1994-07-05 | 85
satomiの回答
SQL文
SELECT I1.req_date,I1.req_qty,(SELECT SUM(req_qty)
FROM InventoryAdjustments I2
WHERE I1.req_date>=I2.req_date)as req_onhand_qty
FROM InventoryAdjustments I1;
考え方
- SELECT節の副問合わせを考える。
- 自己結合を使う
- 1994-07-01→1994-07-01
- 1994-07-02→1994-07-01,1994-07-02......
- このように、I1.req_dateと日付が同じかそれ以前の、要求数量の合計を計算する。
- InventoryAdjustments I1から要求日、要求数量、累計を求める。
実行結果
------------+---------+----------------+
req_date | req_qty | req_onhand_qty |
-----------+---------+----------------+
1994-07-01 | 100 | 100 |
1994-07-02 | 120 | 220 |
1994-07-03 | -150 | 70 |
1994-07-04 | 50 | 120 |
1994-07-05 | -35 | 85 |
おさらい
PostgreSQLで解1と解2のコストを計算してみました。
解1の処理コスト
QUERY PLAN
--------------------------------------------------------------------------------
--------------------------------------------------------------------------
Index Scan using inventoryadjustments_pkey on inventoryadjustments a1 (cost=0.
00..56302.10 rows=1940 width=8) (actual time=0.332..0.543 rows=5 loops=1)
SubPlan
-> Aggregate (cost=28.97..28.98 rows=1 width=4) (actual time=0.053..0.054
rows=1 loops=5)
-> Bitmap Heap Scan on inventoryadjustments a2 (cost=9.26..27.35 ro
ws=647 width=4) (actual time=0.016..0.021 rows=3 loops=5)
Recheck Cond: (req_date <= $0)
-> Bitmap Index Scan on inventoryadjustments_pkey (cost=0.00.
.9.10 rows=647 width=0) (actual time=0.009..0.009 rows=3 loops=5)
Index Cond: (req_date <= $0)
Total runtime: 0.811 ms
(8 行)
解2の処理コスト
QUERY PLAN
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
---
GroupAggregate (cost=0.00..47677.40 rows=200 width=12) (actual time=0.106..0.2
63 rows=5 loops=1)
-> Nested Loop (cost=0.00..38265.91 rows=1254533 width=12) (actual time=0.0
45..0.184 rows=15 loops=1)
-> Index Scan using inventoryadjustments_pkey on inventoryadjustments
a1 (cost=0.00..77.35 rows=1940 width=8) (actual time=0.022..0.033 rows=5 loops=
1)
-> Index Scan using inventoryadjustments_pkey on inventoryadjustments
a2 (cost=0.00..11.60 rows=647 width=8) (actual time=0.005..0.012 rows=3 loops=5
)
Index Cond: (a2.req_date <= a1.req_date)
Total runtime: 0.464 ms
(6 行)
GROUP BYを使った解2より、サブクエリを使った解1のほうが早いはずですが・・・以上より、解2の方がコストが低いってなぜですかね* ̄O ̄)ノ
最終更新:2008年04月18日 17:57