Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
お世話になります。教えてください。縦のデータの時間差の計算が思いつきません。
時刻 | アクション | ログインしていた時間 |
7:10:00 | ログイン | NULL |
8:00:45 | 作業1 | NULL |
10:00:50 | 作業2 | NULL |
13:34:54 | ログオフ | NULL |
というcsvがある場合に、ロードスクリプト内でログオフの行にログインしていた時間をセットしたいのです。
ロード後
時刻 | アクション | ログインしていた時間 |
7:10:00 | ログイン | NULL |
8:00:45 | 作業1 | NULL |
10:00:50 | 作業2 | NULL |
13:34:54 | ログオフ | 6:24:54 |
としたいのですが、こうのように縦のレコードにおいて、特定の時間から特定の時間を引くという処理はどのようにすれば可能でしょうか? お手数ですがご教示願えたら幸いです。
下記スクリプトでどうでしょうか。
一応、作業者が複数いるという前提で記述してます。
日にちをまたぐ場合は、TimeStampを使用する必要があるのと時刻の変換処理を考えないといけないかと。
Sample:
LOAD * INLINE [
ID,時刻, アクション
1,7:10:00, ログイン
2,7:20:00, ログイン
1,8:00:45, 作業1
2,9:00:50, 作業2
1,10:00:50, 作業2
1,13:34:54, ログオフ
2,13:40:45, 作業1
2,14:24:54, ログオフ
];
Join
LOAD
ID,
時刻,
アクション,
time(if(Peek(アクション)='ログイン' and アクション='ログオフ',time(時刻)-time(peek(時刻)))) as ログインしていた時間
Resident Sample
where アクション like 'ログ*'
Order by ID;
下記のような形で可能です。
Sample:
LOAD * INLINE [
ID,時刻, アクション
1,7:10:00, ログイン
2,7:20:00, ログイン
1,8:00:45, 作業1
2,9:00:50, 作業2
1,10:00:50, 作業2
1,13:34:54, ログオフ
2,13:40:45, 作業1
2,14:15:45, 作業3
2,14:24:54, ログオフ
];
LOAD
time(if(アクション='ログオフ',time(時刻)-time(peek(時刻,No-LogNo)))) as ログインしていた時間,
*
;
LOAD
RowNo() as No,
ID,
if(アクション='ログイン',0,Peek(LogNo)+1) as LogNo,
時刻,
アクション
Resident Sample
Order by ID,時刻;
DROP Fields No,LogNo;
DROP Table Sample;
スクリプトはDB接続の場合のスクリプトの応用と思ってもらえればいいと思います。
DB接続の場合
LOAD * ;
SQL Select * FROM Table;
のようにLOADが「;」で終了して、後ろのSQL Selectの内容を取り込んでいます。
同じように
LOAD * ;
LOAD * FROM Table;
という記述をすると下のLOADの内容を上のLOADで取り込むことができます。
Qlikでは下のLOADで新たに定義された項目を使用するのに、LOADを重ねて書くことができます。
このようにすると
LOAD A,B,A + B as C FROM Table;
LOAD A,B,C,C*1.5 as D Resident Table;
のように一度ロードされたデータをもう一度Residentでロードするよりも
LOAD C*1.5 as D,
*;
LOAD A,B,A+B as C FROM Table;
のように記述する方がスクリプトがシンプルになります。
今回の上のLOADは下のLOADで定義されたNoとLogNoを使用しています。
Noが全体の行数、LogNoが'ログイン'を0として、ログオフまでの行数を計算しています。
それで全体の行数からログオフの行数を引くことでログインの行数が何行目かを特定しています。
Drop Fieldsの部分をコメントアウトして、リロードし直してもらうと考え方がわかると思います。
この説明で大丈夫ですか?
下記スクリプトでどうでしょうか。
一応、作業者が複数いるという前提で記述してます。
日にちをまたぐ場合は、TimeStampを使用する必要があるのと時刻の変換処理を考えないといけないかと。
Sample:
LOAD * INLINE [
ID,時刻, アクション
1,7:10:00, ログイン
2,7:20:00, ログイン
1,8:00:45, 作業1
2,9:00:50, 作業2
1,10:00:50, 作業2
1,13:34:54, ログオフ
2,13:40:45, 作業1
2,14:24:54, ログオフ
];
Join
LOAD
ID,
時刻,
アクション,
time(if(Peek(アクション)='ログイン' and アクション='ログオフ',time(時刻)-time(peek(時刻)))) as ログインしていた時間
Resident Sample
where アクション like 'ログ*'
Order by ID;
ありがとうございます!!
追加でご質問ですが、本件の場合、ログオン、ログオフの順番になっているはずなので一応それを確認したうえで1つ前の行であるログオン時刻を使うというものですが、peekで1行前ではなく、何かの条件によって2行前や3行前などにある任意の行(ログイン時刻)を見るということは可能でしょうか?よろしくお願いいたします
Peek関数は行番号指定できるので、できると思いますがデータ詳細とと
条件がわからないと具体的な回答は難しいです、
アドバイスありがとうございます。Whereで’ログ’のみに絞らず、縦に作業1や作業2などを挟んでいる場合、それを飛び越えて前のログインの行をpeekするということが可能か伺いたかったのです
一番はじめの質問に関する解決法としては ’ログイン’’ログアウト’で絞って1行前を見ることで、問題なくできるようになっています。peekのより高度な使い方として知りたかったので追加で質問させていただきました
下記のような形で可能です。
Sample:
LOAD * INLINE [
ID,時刻, アクション
1,7:10:00, ログイン
2,7:20:00, ログイン
1,8:00:45, 作業1
2,9:00:50, 作業2
1,10:00:50, 作業2
1,13:34:54, ログオフ
2,13:40:45, 作業1
2,14:15:45, 作業3
2,14:24:54, ログオフ
];
LOAD
time(if(アクション='ログオフ',time(時刻)-time(peek(時刻,No-LogNo)))) as ログインしていた時間,
*
;
LOAD
RowNo() as No,
ID,
if(アクション='ログイン',0,Peek(LogNo)+1) as LogNo,
時刻,
アクション
Resident Sample
Order by ID,時刻;
DROP Fields No,LogNo;
DROP Table Sample;
びっくりしました、なんだか天才のようなスクリプト
peekが前行だけじゃなく、前にも後ろにも行けることもわかり、最終的にはなんとなくやっていることが分かるのですが、このスクリプト自体が初心者の理解を超えています。すみません(;^_^A
まずinlineロードはもちろんわかります
次に突然LOAD time(if(アクション・・・・ これが突然出てくるのはどういうことでしょうか?NoもLogNoもまだ出てきてないのに・・・
そして最後のLOAD・・
本当に申し訳ありません。てっきりQVのスクリプトは上から順次、処理して下に降りてくると思っていました。私の言っていることが逆に素人すぎて変かも知れませんが、お手すきの際に、真ん中のLOADがまだNoやLogNoが出てきていない状況で一体何をしているのか?
また最後のLOADで「ログインしていた時間」が書かれていないのに、項目としてセットされてくるあたり、文章で解説いただけましたら非常に助かります。すみませんが宜しくお願いいたします。
スクリプトはDB接続の場合のスクリプトの応用と思ってもらえればいいと思います。
DB接続の場合
LOAD * ;
SQL Select * FROM Table;
のようにLOADが「;」で終了して、後ろのSQL Selectの内容を取り込んでいます。
同じように
LOAD * ;
LOAD * FROM Table;
という記述をすると下のLOADの内容を上のLOADで取り込むことができます。
Qlikでは下のLOADで新たに定義された項目を使用するのに、LOADを重ねて書くことができます。
このようにすると
LOAD A,B,A + B as C FROM Table;
LOAD A,B,C,C*1.5 as D Resident Table;
のように一度ロードされたデータをもう一度Residentでロードするよりも
LOAD C*1.5 as D,
*;
LOAD A,B,A+B as C FROM Table;
のように記述する方がスクリプトがシンプルになります。
今回の上のLOADは下のLOADで定義されたNoとLogNoを使用しています。
Noが全体の行数、LogNoが'ログイン'を0として、ログオフまでの行数を計算しています。
それで全体の行数からログオフの行数を引くことでログインの行数が何行目かを特定しています。
Drop Fieldsの部分をコメントアウトして、リロードし直してもらうと考え方がわかると思います。
この説明で大丈夫ですか?
>という記述をすると下のLOADの内容を上のLOADで取り込むことができます。
>Qlikでは下のLOADで新たに定義された項目を使用するのに、LOADを重ねて書くことができます。
有難うございます。全然知りませんでした。
びっくりしています。
今までてっきり上から順に定義してqvdに一旦中間ファイルを吐き、それを再度読み直して順次処理を行っていました。本当にありがとうございました。(^^♪