SQL Query显示工单的顺序

时间:2015-12-17 14:02:45

标签: sql sql-server sql-server-2008

首先对不好的主题线抱歉。

编辑:此处的查询重复OrderNumbers我需要查询不重复OrderNumbers 编辑:缩短问题并提供更清晰的问题

我有一张表,其中包含已执行的所有工单的记录。有两种类型的订单。安装和故障呼叫。我的查询是查找在安装后30天内发生的所有故障呼叫,并将该故障呼叫(TC)与正确的安装(IN)相匹配。因此,故障呼叫日期必须在安装后发生,但不会超过30天。此外,如果同一帐户有两个安装和两个故障呼叫都在30天内发生,并且它们按顺序发生,结果必须反映出来。我遇到的问题是我得到的安装订单与两个不同的故障呼叫(TC)和一个与两个不同的安装(IN)匹配的故障呼叫(TC)相匹配

在SQL Fiddle的示例中,请密切关注安装订单号1234567810和故障呼叫订单号1234567890,您将看到我遇到的问题。 http://sqlfiddle.com/#!3/811df/8

select b.accountnumber,
       MAX(b.scheduleddate) as OriginalDate,
       b.workordernumber as OriginalOrder,
       b.jobtype as OriginalType,
       MIN(a.scheduleddate) as NewDate,
       a.workordernumber as NewOrder,
       a.jobtype as NewType 
from (
      select workordernumber,accountnumber,jobtype,scheduleddate 
      from workorders 
      where jobtype = 'TC'
     ) a join 
     (
       select workordernumber,accountnumber,jobtype,scheduleddate 
       from workorders  
       where jobtype = 'IN'
     ) b
on a.accountnumber = b.accountnumber 
group by b.accountnumber,
         b.scheduleddate,
         b.workordernumber,
         b.jobtype, 
         a.accountnumber,
         a.scheduleddate,
         a.workordernumber,
         a.jobtype
having MIN(a.scheduleddate) > MAX(b.scheduleddate) and 
      DATEDIFF(day,MAX(b.scheduleddate),MIN(a.scheduleddate)) < 31

我正在寻找结果的示例。 感谢您在为我指路的过程中提供的任何帮助。 enter image description here

2 个答案:

答案 0 :(得分:0)

你其实很亲密。我意识到你真正想要的是MIN() TC日期,该日期大于该帐号的每个安装日期,只要它们相隔30天或更短。

所以你真的需要按结果集中的安装日期进行分组,不包括WorkOrderNumber。类似的东西:

SELECT a.AccountNumber, MIN(a.scheduleddate) TCDate, b.scheduleddate INDate
FROM 
    (
        SELECT WorkOrderNumber, ScheduledDate, JobType, AccountNumber
        FROM workorders
        WHERE JobType = 'TC'
    ) a
    INNER JOIN
    (
        SELECT WorkOrderNumber, ScheduledDate, JobType, AccountNumber
        FROM workorders
        WHERE JobType = 'IN'
    ) b
    ON a.AccountNumber = b.AccountNumber
WHERE b.ScheduledDate < a.ScheduledDate
    AND DATEDIFF(DAY, b.ScheduledDate, a.ScheduledDate) <= 30
GROUP BY a.AccountNumber, b.AccountNumber, b.ScheduledDate

这会处理日期和AccountNumber,但您仍需要WorkOrderNumber,因此我将workorders表格加回两次,每种类型一次。

注意:我假设每个工单都有一个每个帐号的唯一日期。因此,如果您在'1/1/2015'上完成了帐户1的工作订单1('TC'),并且您在2015年1月1日完成了帐户1的工作订单2('TC'),那么我可以不保证结果集中有正确的WorkOrderNumber

我的最终查询如下:

SELECT 
    aggdata.AccountNumber, inst.workordernumber OriginalWorkOrderNumber, inst.JobType OriginalJobType, inst.ScheduledDate OriginalScheduledDate,
    tc.WorkOrderNumber NewWorkOrderNumber, tc.JobType NewJobType, tc.ScheduledDate NewScheduledDate
FROM (
        SELECT a.AccountNumber, MIN(a.scheduleddate) TCDate, b.scheduleddate INDate
        FROM 
            (
                SELECT WorkOrderNumber, ScheduledDate, JobType, AccountNumber
                FROM workorders
                WHERE JobType = 'TC'
            ) a
            INNER JOIN
            (
                SELECT WorkOrderNumber, ScheduledDate, JobType, AccountNumber
                FROM workorders
                WHERE JobType = 'IN'
            ) b
            ON a.AccountNumber = b.AccountNumber
        WHERE b.ScheduledDate < a.ScheduledDate
            AND DATEDIFF(DAY, b.ScheduledDate, a.ScheduledDate) <= 30
        GROUP BY a.AccountNumber, b.AccountNumber, b.ScheduledDate
    ) aggdata
    LEFT OUTER JOIN workorders tc
    ON aggdata.TCDate = tc.ScheduledDate
        AND aggdata.AccountNumber = tc.AccountNumber
        AND tc.JobType = 'TC'
    LEFT OUTER JOIN workorders inst
    ON aggdata.INDate = inst.ScheduledDate
        AND aggdata.AccountNumber = inst.AccountNumber
        AND inst.JobType = 'IN'

答案 1 :(得分:0)

select in1.accountnumber,
       in1.scheduleddate as OriginalDate,
       in1.workordernumber as OriginalOrder,
       'IN' as OriginalType,
       tc.scheduleddate as NewDate,
       tc.workordernumber as NewOrder,
       'TC' as NewType 
from 
      workorders in1
      out apply   (Select min(in2.scheduleddate) as scheduleddate  from workorders in2 Where  in2.jobtype = 'IN' and in1.accountnumber=in2.accountnumber and in2.scheduleddate>in1.scheduleddate) ins
      join workorders tc on tc.jobtype = 'TC' and tc.accountnumber=in1.accountnumber and tc.scheduleddate>in1.scheduleddate and (ins.scheduleddate is null or tc.scheduleddate<ins.scheduleddate) and DATEDIFF(day,in1.scheduleddate,tc.scheduleddate) < 31
        Where     in1.jobtype = 'IN'