6

这是我的数据示例以及我希望看到的内容:

JOB    OPSEQ    OPCOMPLETE   OPCODE

100     1        yes          pull  
100     2        yes          weld  
100     3        no           grind    
100     4        no           machine  
100     5        no           asmbl  

所以我想选择 opcomplete=no 的 min(opseq) 和 opcomplete=yes 的 max(opseq),以及 min 和 max opseq 的操作码。在这个例子中,这将是:
min(opseq):3
opcode of min op:grind
max(opseq):2 opcode of max op:weld

我正在寻找这个的原因是为了获得不完整的最小 opseq 的操作码。
我让最小和最大 opseqs 工作得很好。这就是我所拥有的:

(SELECT   company, jobnum, MAX(oprseq) AS maxclosed, opcomplete
 FROM     joboper AS joboper_2
 WHERE    (company = 'lot') AND (opcomplete = '1')
 GROUP BY company, jobnum, opcomplete) AS t_joboper1 ON joboper.company = t_joboper1.company AND joboper.jobnum = t_joboper1.jobnum INNER JOIN
(SELECT   company, jobnum, MIN(oprseq) AS minopen, opcomplete
 FROM     joboper AS joboper_1
 WHERE    (company = 'lot') AND (opcomplete = '0')
 GROUP BY company, jobnum, opcomplete) AS t_joboper2 ON joboper.company = t_joboper2.company AND joboper.jobnum = t_joboper2.jobnum  

因此,当我尝试添加我的操作码时,它不起作用,我开始获取各种重复值。这是我写的:

(SELECT   company, jobnum, MAX(oprseq) AS maxclosed, opcomplete, opcode as maxopcode
 FROM     joboper AS joboper_2
 WHERE    (company = 'lot') AND (opcomplete = '1')
 GROUP BY company, jobnum, opcomplete, opcode) AS t_joboper1 ON joboper.company = t_joboper1.company AND joboper.jobnum = t_joboper1.jobnum INNER JOIN
(SELECT   company, jobnum, MIN(oprseq) AS minopen, opcomplete, opcode as minopcode
 FROM     joboper AS joboper_1
 WHERE    (company = 'lot') AND (opcomplete = '0')
 GROUP BY company, jobnum, opcomplete, opcode) AS t_joboper2 ON joboper.company = t_joboper2.company AND joboper.jobnum = t_joboper2.jobnum  

这是我目前的整个代码(操作码提取所有重复值:

SELECT     jobhead.company, jobhead.jobnum, jobhead.partnum, 
           jobhead.partdescription, jobhead.startdate, 
           jobhead.reqduedate, jobhead.prodqty, jobhead.qtycompleted,
           joboper.oprseq, joboper.opcode, joboper.opcomplete, 
           joboper.qtycompleted AS joboperqtycomplete, 
           resourcegroup.description AS rgroupdescription,
           dmrhead.dmrnum, poheader.ponum, vendor.name AS vendorname,
           t_joboper2.minopen AS minopen, t_joboper2.minopcode AS minopcode,
           t_joboper1.maxclosed AS maxclosed, t_joboper1.maxopcode AS maxopcode
FROM       jobhead LEFT OUTER JOIN
           joboper INNER JOIN
           (SELECT   company, jobnum, MAX(oprseq) AS maxclosed, 
                     opcomplete, opcode as maxopcode
            FROM     joboper AS joboper_2
            WHERE    (company = 'lot') AND (opcomplete = '1')
            GROUP BY company, jobnum, opcomplete, opcode) AS t_joboper1 
              ON     joboper.company = t_joboper1.company 
            AND      joboper.jobnum = t_joboper1.jobnum INNER JOIN
           (SELECT   company, jobnum, MIN(oprseq) AS minopen, opcomplete, 
                     opcode as minopcode
            FROM     joboper AS joboper_1
            WHERE    (company = 'lot') AND (opcomplete = '0')
            GROUP BY company, jobnum, opcomplete, opcode) AS t_joboper2 
              ON     joboper.company = t_joboper2.company
            AND      joboper.jobnum = t_joboper2.jobnum 
              ON     jobhead.company = joboper.company
            AND      jobhead.jobnum = joboper.jobnum LEFT OUTER JOIN
                     resourcegroup ON joboper.company = resourcegroup.company
            AND      joboper.opcode = resourcegroup.opcode LEFT OUTER JOIN
                     dmrhead ON joboper.company = dmrhead.company
            AND      joboper.jobnum = dmrhead.jobnum
            AND      joboper.assemblyseq = dmrhead.assemblyseq 
            AND      joboper.oprseq = dmrhead.oprseq LEFT OUTER JOIN
                     porel ON joboper.company = porel.company
            AND      joboper.jobnum = porel.jobnum
            AND      joboper.assemblyseq = porel.assemblyseq
            AND      joboper.oprseq = porel.jobseq LEFT OUTER JOIN
                     podetail ON porel.company = podetail.company
            AND      porel.ponum = podetail.ponum 
            AND      porel.poline = podetail.poline LEFT OUTER JOIN
                     poheader ON podetail.company = poheader.company 
            AND      podetail.ponum = poheader.ponum LEFT OUTER JOIN
                     vendor ON poheader.company = vendor.company
            AND      poheader.vendornum = vendor.vendornum  
WHERE     (jobhead.jobreleased = 1)
 AND      (jobhead.jobcomplete = 0) 
 AND      (jobhead.company = 'lot') 
 AND      (jobhead.plant = '001')  

我希望这一切都对我在这里尝试做的事情有意义。如果不是很明显,这是我第一次在这里提问。提前感谢所有帮助!

新 - 2012 年 12 月 21 日

谢谢你们的帮助!我尝试了您的两个建议,但都无法获得我想要的确切结果。但是每个答案都帮助我最终得到了我需要的东西。由于这是我的第一个问题,所以我不知道应该怎么做才能将哪个答案标记为解决方案?就像我说的,这两个答案都帮了我很多,我认为我无法从他们那里得到我想要的结果的原因完全是我的错。在进行了更多工作之后,我意识到即使我非常努力地想清楚我的问题,但当我回过头来时,我发现我可以用更好的措辞来表达问题。再次,我非常感谢所有的帮助,我期待在未来提出更好的问题!
顺便说一句,这是最终起作用的代码。

 SELECT     jobhead.company, jobhead.jobnum, jobhead.partnum, jobhead.partdescription, jobhead.startdate, jobhead.reqduedate, jobhead.prodqty, jobhead.qtycompleted, 
                  joboper.oprseq, joboper.opcode, joboper.opcomplete, joboper.qtycompleted AS joboperqtycomplete, resourcegroup.description AS rgroupdescription, 
                  dmrhead.dmrnum, poheader.ponum, vendor.name AS vendorname, t_joboper2.minopen, t_joboper1.maxclosed, t_joboper3.opcode AS minopcode
FROM         jobhead LEFT OUTER JOIN
                  joboper INNER JOIN
                      (SELECT     company, jobnum, MAX(oprseq) AS maxclosed, opcomplete
                        FROM          joboper AS joboper_1
                        WHERE      (company = 'lot') AND (opcomplete = '1')
                        GROUP BY company, jobnum, opcomplete) AS t_joboper1 ON joboper.company = t_joboper1.company AND joboper.jobnum = t_joboper1.jobnum INNER JOIN
                      (SELECT     company, jobnum, MIN(oprseq) AS minopen, opcomplete
                        FROM          joboper AS joboper_2
                        WHERE      (company = 'lot') AND (opcomplete = '0')
                        GROUP BY company, jobnum, opcomplete) AS t_joboper2 ON joboper.company = t_joboper2.company AND 
                  joboper.jobnum = t_joboper2.jobnum INNER JOIN
                      (SELECT     company, jobnum, oprseq, opcomplete, opcode
                        FROM          joboper AS joboper_3
                        WHERE      (company = 'lot') AND (opcomplete = '0'))
                         AS t_joboper3 ON t_joboper2.company = t_joboper3.company AND t_joboper2.jobnum = t_joboper3.jobnum AND 
                  t_joboper2.minopen = t_joboper3.oprseq ON jobhead.company = joboper.company AND jobhead.jobnum = joboper.jobnum LEFT OUTER JOIN
                  resourcegroup ON joboper.company = resourcegroup.company AND joboper.opcode = resourcegroup.opcode LEFT OUTER JOIN
                  dmrhead ON joboper.company = dmrhead.company AND joboper.jobnum = dmrhead.jobnum AND joboper.assemblyseq = dmrhead.assemblyseq AND 
                  joboper.oprseq = dmrhead.oprseq LEFT OUTER JOIN
                  porel ON joboper.company = porel.company AND joboper.jobnum = porel.jobnum AND joboper.assemblyseq = porel.assemblyseq AND 
                  joboper.oprseq = porel.jobseq LEFT OUTER JOIN
                  podetail ON porel.company = podetail.company AND porel.ponum = podetail.ponum AND porel.poline = podetail.poline LEFT OUTER JOIN
                  poheader ON podetail.company = poheader.company AND podetail.ponum = poheader.ponum LEFT OUTER JOIN
                  vendor ON poheader.company = vendor.company AND poheader.vendornum = vendor.vendornum
WHERE     (jobhead.jobreleased = 1) AND (jobhead.jobcomplete = 0) AND (jobhead.company = 'lot') AND (jobhead.plant = '001')            
4

3 回答 3

5

这是一种方法:

select JOB,
       min(case when OPCOMPLETE = 'no' then OPSEQ end) as MIN_NO_OPSEQ,
       min(case when OPCOMPLETE = 'no' then OPCODE end) as MIN_NO_OPCODE,
       min(case when OPCOMPLETE = 'yes' then OPSEQ end) as MAX_YES_OPSEQ,
       min(case when OPCOMPLETE = 'yes' then OPCODE end) as MAX_YES_OPCODE
  from ( select JOB,
                OPSEQ,
                OPCOMPLETE,
                OPCODE,
                rank() over (partition by JOB, OPCOMPLETE order by OPSEQ asc) as R_NO,
                rank() over (partition by JOB, OPCOMPLETE order by OPSEQ desc) as R_YES
           from TABLE_NAME
       )
 where OPCOMPLETE = 'no' and R_NO = 1    -- row with min(OPSEQ) where OPCOMPLETE = 'no'
    or OPCOMPLETE = 'yes' and R_YES = 1  -- row with max(OPSEQ) where OPCOMPLETE = 'yes'
 group
    by JOB
;

笔记:

  • 未测试。
  • 在第 2-5 行中,每个min都可以更改为max无效,因为只有一行满足所有必要的标准。(minmax) 仅是必需的,因为group by:我们通过选择非空值将两行合并为一。
  • 有关信息rank(),请参阅MSDN 上的文档
于 2012-12-20T20:35:37.670 回答
3

我认为这比你做的要容易得多,只要 OPSEQ 是一个独特的值:

select
    opseq, opcode
from
    joboper
where
    opseq in (select min(opseq) from joboper where opcomplete = 'no')
    or
    opseq in (select max(opseq) from joboper where opcomplete = 'yes')
于 2012-12-20T20:58:36.200 回答
1

假设您使用的是 SQL Server 2005 或更高版本,您还可以考虑使用CROSS APPLY,如下所示:

SELECT
  j.JOB,
  y.OPSEQ  AS LastCompleteOPSEQ,
  y.OPCODE AS LastCompleteOPCODE,
  n.OPSEQ  AS FirstIncompleteOPSEQ,
  n.OPCODE AS FirstIncompleteOPCODE
FROM (SELECT DISTINCT JOB FROM joboper) j
CROSS APPLY (
  SELECT TOP 1 OPSEQ, OPCODE
  FROM joboper
  WHERE JOB = j.JOB AND OPCOMPLETE = 'yes'
  ORDER BY OPSEQ DESC
) y
CROSS APPLY (
  SELECT TOP 1 OPSEQ, OPCODE
  FROM joboper
  WHERE JOB = j.JOB AND OPCOMPLETE = 'no'
  ORDER BY OPSEQ ASC
) n
;

您可以在 SQL Fiddle查询它。

于 2012-12-22T20:23:46.710 回答