2013-05-21 28 views
2

我目前正在通過VBA做到這一點,但如果我能夠在查詢中獲得一些幫助,它確實爲我節省了大量時間。如何在sql查詢中執行此步驟?

這是我正在處理的這份報告中需要做的5件事情之一。


我從3頁不同的表
tableB的閱讀

TableA TableB TableC 

字段從表A

OUT_ID 

timestamp 
event_type 
worker 
operator_id 
new_date 

字段從表C

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 

這是我需要做的。

Event_type列,如果RET_CHANCE下一行中有WORKER_RET_COMMENT_CHANCE然後檢查OUT_ID是一樣的,如果是相同的比是否TIMESTAMP差小於10秒,如果不是從黃色的單元格複製WORKER數這一切都是真的紅細胞。

請參閱圖像打擊和附加excel文件的示例。 Download excel file via dropbox

enter image description here

+0

我把它的恩賜或貝寶聘用,但我需要的不僅僅是1步以上。如果有人有興趣,請通過電子郵件與我聯繫 – Mowgli

+0

你最好正式定義這些記錄的順序,因爲沒有它,「下一行」是毫無意義的。 –

+0

@DavidAldridge很少有'WORKER_ERT_COMMENT_CHANCE'將在最上面的一行,'RET_CHANCE'將會在下一行,如果這種情況比我需要執行相同的步驟。回到你的問題,它是由'TableA.OUT_ID','TableA .timestamp' – Mowgli

回答

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 
+0

謝謝,我從來沒有使用過查看,只是看着它在我看來。 – Mowgli

+0

我剛剛命名您的結果數據集爲'View1',所以我不必將您的整個查詢包含到我的答案中。 –

+0

* ABS(EXTRACT(SECOND FROM v1.timestamp) - EXTRACT(SECOND FROM v2.timestamp))<10 *不正確。這會減去時間戳的第二個分量。 –

1

看到你有一個「下一行」的要求它像seemss使用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語句來fullfill剩餘需求

  • 如果EVENT_TYPE是RET_CHANCE
  • 而下一行的事件類型是WORKER_RET_COMMENT_CHANCE
  • 而從兩排的時間戳小於然後在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 

注:

  • 你不需要在這裏與子句中使用的,但它會使CASE聲明不可讀。
  • 我留在所有的NEXT_ *字段中,以便您可以看到查詢的工作方式。
  • 使用傑弗裏·肯普的answer計算秒差

DEMO

+0

在Oracle中減去DATE類型字段會產生**天**。你不是在用你的邏輯去釋放時間部分嗎? –

+0

@ PM77-1我猜這個證明是在布丁中。它沒有在[SQLFiddle](http://sqlfiddle.com/#!4/764a6/33)中查看Diff列。當我嘗試使用[Extract方法它不起作用](http://sqlfiddle.com/#!4/764a6/29)。另請注意,asktom文章使用日期數據類型 –

+0

@ConradFrix您能告訴我輸出是如何讀取的嗎? – Mowgli