初級帳票編 顧客別来店回数

本章では、初級コマンドで用いた1996年1月のデータを用いて、下図に示すような「顧客別来店回数」の帳票を作成する。

出力結果

顧客別来店回数

チュートリアル初級シナリオ編

顧客 来店回数
2010216000013 19
2010216000020 3
2010216000037 2
2010216000051 2
2010216000068 1
2010216000075 1
2010216000099 6
2010216000105 5
2010216000136 6
2010216000174 3
2010216000204 3
2010216000211 7
2010216000228 8
2010216000259 1
2010216000280 7

処理の流れ

上図の帳票を作成するにあたり、これまでに学習したコマンド以外に必要となるコマンドは、「NULL値を含む行を削除する」コマンドである。
まずは、次に示す回答見ずに、各自で、入力データから、上図の帳票を作成するために、コマンドをどのように組み合わせて実行すればよいか(処理の流れ)を考えてもらいたい。

回答:処理の流れ

  1. 顧客がNULLである行を削除する
  2. 必要な項目「顧客」「日付」を選ぶ
  3. 顧客と日付で行を単一化する
  4. 顧客別行数をカウントし、「来店回数」項目とする
  5. 出力する項目「顧客」、「来店回数」項目を抜き出す

ここで来店回数の定義の問題が出てくる。来店回数を考えるとき、何をもって一回の来店とするかによって三通りの考え方がある。一つは、顧客別のレシート枚数を来店回数と見なすという方法である。しかし、お客さんが一旦精算をすませ、その時にレジ周りにある買い忘れ品に気づき、その場で再び精算をした場合、それぞれの精算におけるレシート番号は異なってくる。レシート枚数を来店回数と見なすと、このようなケースを2回の来店とカウントしてしまう。
 二つ目の方法は、この問題を解決するために、ある顧客が一日に何回きたとしても、それは一回の来店と見なす方法がある。しかし一方で、ある顧客が朝と夜との2回来店したとしても、それは一回の来店として見なされてしまう。
 三つ目の方法は上記二つの方法を組合せ、ある顧客について、ある時間内(例えば5分内)に発生したレシートは同じ来店と見なすという方法である。この方法の欠点は処理が非常に複雑になる点である。
 上記に示した回答は、二つ目の方法に基づいている。一つ目の方法を採用したければ、「日付+レシート番号」でレシートを識別するようにすればよい。ここでレシート番号だけの項目を使うのではなく日付を使うのは、通常、レジのレシート番号は、桁数が限られているために番号を使いまわしており、レシート番号だけを使うと、その番号が重複してしまう可能性があるからである。最後に三つ目の方法は簡単ではないため、上級シナリオ編で解説する。

次に、上記の「処理の流れ」における1の処理について解説する。

NULL値を含む行を削除する(xtdelnul)

xtdelnul は、-fで指定した項目がNULL("*"で表される)である行を削除する。

上述の処理の流れにおいては、「xtdelnul -f 顧客」と指定すればよい。

スクリプト

以上の説明で、顧客別来店回数を求めるスクリプトを書く準備が整った。以下にその回答を示すが、回答を見る前に各自でチャレンジしてもらいたい。

#/bin/bash
#===============================================================
# MUSASHI bash script
#===============================================================

#---- タイトル
title="顧客別来店回数"

#---- コメント
comment="チュートリアル初級シナリオ編"

#---- 各種変数(適宜修正すること)
inPath="/mnt/h00/prm/tutorial"

#---------------------------------------------------------------
# コマンド
#---------------------------------------------------------------
xtdelnul -f 顧客 -i $inPath/dat.xt.gz |
xtcut -f 顧客,日付 |
xtuniq -k 顧客,日付 |
xtcount -k 顧客 -a 来店回数 |
xtcut -f 顧客,来店回数 |
xtheader -l "$title" -c "$comment" -o cusvisit.xt
#===============================================================

実行結果は各自で確認してもらいたい。

次に、レシート番号による来店回数の求め方のスクリプトを加えて、それら二つを結合するスクリプトを考えて見よう。

上記のスクリプト以降の処理の流れは以下のようになるであろう。

  1. 顧客がNULLである行を削除する
  2. 必要な項目「顧客」「日付」「レシート番号」を選ぶ
  3. 顧客と日付、レシート番号で行を単一化する
  4. 顧客別行数をカウントし、「来店回数2」項目とする
  5. そこに以前に作ったファイルcustvisit.xtから「来店回数」項目を結合する。
  6. 最後に出力する項目「顧客」、「来店回数」、「来店回数2」の項目を抜き出す

実際のスクリプトは以下のようになるであろう。実行結果は各自で確認してもらいたい。

#/bin/bash
#===============================================================
# MUSASHI bash script
#===============================================================

#---- タイトル
title="顧客別来店回数"

#---- コメント
comment="チュートリアル初級シナリオ編"

#---- 各種変数(適宜修正すること)
inPath="/mnt/h00/prm/tutorial"

#---------------------------------------------------------------
# コマンド
#---------------------------------------------------------------
xtdelnul -f 顧客 -i $inPath/dat.xt.gz |
xtcut -f 顧客,日付 |
xtuniq -k 顧客,日付 |
xtcount -k 顧客 -a 来店回数 |
xtcut -f 顧客,来店回数 >xxa

xtdelnul -f 顧客 -i $inPath/dat.xt.gz |
xtcut -f 顧客,日付,レシート番号 |
xtuniq -k 顧客,日付,レシート番号 |
xtcount -k 顧客 -a 来店回数2 |
xtjoin -k 顧客 -m xxa -f来店回数 -|
xtcut -f 顧客,来店回数,来店回数2 |
xtheader -l "$title" -c "$comment" -o cusvisit.xt
#===============================================================

練習課題