2

私は現在、VBA を介してこの Excel を実行していますが、クエリでそれを行うための助けを得ることができれば、本当に多くの時間を節約できます。

これは、私が取り組んでいるこのレポートのために行う必要がある 5 つのことのうちの 1 つです。


3つの異なるテーブルから読んでいるテーブル

TableA   TableB  TableC

tableAのフィールド

OUT_ID

tableBのフィールド

timestamp
event_type
worker
operator_id
new_date

tableCのフィールド

worker

クエリ

Select
       TableA.OUT_ID,
       TableB.timestamp,
       TableB.new_date,
       TableB.event_type,
       TableC.worker,
       TableB.operator_id

From TableA left outer join
        TableB 
           ON TableA.OUT_ID = TableB.OUT_ID and
                 TableB.event_type in ('WORKER_RET_CMT_CHANCE','RET_CHANCE','WORKER_STATUS_CHANCE') Left OUTER JOIN 
              TableC 
                ON TableB.worker = TableC.worker
 where  TableA.time_stamp > {?PickDate} //parameter in crystal report to pick date
    and TableA.time_stamp < {?RestDate}  //parameter in crystal report to pick date 
   order by TableA.OUT_ID, TableB.timestamp

これが私がしなければならないことです。

に次の行がある場合は同じかどうかを確認し、同じ場合は差が 10 秒未満かどうかを確認し、これがすべて当てはまる場合は黄色のセルから赤いセルに番号をコピーします。Event_typeRET_CHANCEWORKER_RET_COMMENT_CHANCEOUT_IDTIMESTAMPWORKER

サンプルは画像ブローと添付エクセルファイルをご覧ください。 ドロップボックス経由でエクセルファイルをダウンロード

ここに画像の説明を入力

4

2 に答える 2

1

「次の行」の要件があることを考えると、LEAD関数を使用するのに適した時期に思えます。

ドキュメントに記載されているように

LEAD は分析関数です。自己結合なしで、テーブルの複数の行に同時にアクセスできます。クエリから返された一連の行とカーソルの位置を指定すると、LEAD はその位置を超えた特定の物理オフセットで行へのアクセスを提供します。

したがって、「次のイベント」、「次のタイムスタンプ」、「次のワーカー」を取得するには、次のことを行う必要があります

LEAD(timestamp) OVER (ORDER BY ???) next_timestamp, 
LEAD(EVENT_TYPE) OVER (ORDER BY ???) next_event,
LEAD(WORKER) OVER (ORDER BY ??) NEXT_WORKER

ここでの ORDER BY 句は、「次の行」が何であるかを示しています。あなたが持っていたので

order by TableA.OUT_ID, TableB.timestamp

私たちはできる

... OVER (ORDER BY OUT_ID, timestamp)  

ただし、「OUT_IDが同じかどうかを確認する」という要件もありました。オプションの PARTITION BY 句を追加して、「次のレコード」が同じ OUT_ID に使用されるようにすることができます。

... OVER (PARTITION BY OUT_ID ORDER BY タイムスタンプ)

すべての「次のフィールド」を取得したら、CASE ステートメントを使用して残りの要件を満たすことができます。

  • Event_type が RET_CHANCE の場合
  • 次の行のイベント タイプは WORKER_RET_COMMENT_CHANCE です。
  • そして、2 つの行のタイムスタンプは 10 秒未満です。
  • 次に、次の行のワーカーを使用します

次のクエリは、これらのアイデアのデモンストレーションです。


WITH Data AS (
SELECT 
  OUT_ID,
  timestamp,
  LEAD(timestamp) OVER (PARTITION BY Out_ID ORDER BY TimeStamp) next_timestamp, 
  Event_type,
  LEAD(EVENT_TYPE) OVER (PARTITION BY Out_ID ORDER BY TimeStamp) next_event,
  WORKER,
  LEAD(WORKER) OVER (PARTITION BY Out_ID ORDER BY TimeStamp) NEXT_WORKER
FROM TableB
ORDER BY 
   OUT_ID,
   timestamp
)
SELECT 

  OUT_ID,
  timestamp,
  next_timestamp, 
  Event_type,
  next_event,
  WORKER,
  NEXT_WORKER,
( CAST( next_timestamp AS DATE ) - CAST( timestamp AS DATE ) ) * 86400 DIFF,
  CASE WHEN 
        EVENT_TYPE ='RET_CHANCE'
        AND next_event = 'WORKER_STATUS_CHANCE'
        AND ( CAST( next_timestamp AS DATE ) - CAST( timestamp AS DATE ) ) * 86400  < 10 
       THEN NEXT_WORKER
       ELSE WORKER
   END as CALC_WORKER
FROM 
  data

ノート:

  • ここで with 句を使用する必要はありませんが、使用するとCASEステートメントが判読できなくなります。
  • クエリがどのように機能するかを確認できるように、すべての NEXT_* フィールドを残しました。
  • 秒差を計算するための Jeffrey Kemp の回答の使用

デモ

于 2013-05-21T17:57:51.973 に答える
1

これは完全な答えではなく、タスクを明確にするための試みです。コメントではあまり読みにくいコードが必要です。だから(みんな)我慢してください。

以下は、レコードの正しいペアリングSELF JOINを作成しますか?

FROM View1 v1
JOIN View1 v2 ON v1.out_id = v2.out_id AND 
                 v1.event_type = 'RET_CHANCE' AND v2.event_type = 'WORKER_RET_COMMENT_CHANCE' AND              
                 ABS(EXTRACT(SECOND FROM v1.timestamp) - EXTRACT(SECOND FROM v2.timestamp)) < 10
于 2013-05-21T16:28:36.780 に答える