2013-05-21 29 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