2012-12-20 61 views
6

這裏是我的數據樣本,我想看到的內容:掌握MIN線的其他字段值/最大值

JOB OPSEQ OPCOMPLETE OPCODE 

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

所以我想選擇分鐘(opseq),其中opcomplete = no和max(opseq)其中opcomplete = yes,以及最小和最大opseq的操作碼。在這個例子中,這將是:
分鐘(opseq):分運算的3
操作碼:研磨
MAX(opseq):最大運算的2 操作碼:焊接

我尋找這種情況的原因是得到未完成的最小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 

所以,當我試圖讓我的操作碼加了進來,它沒有工作,我開始gettings各種重複值。這是我寫的:

(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') 

我希望這一切是有道理的我我想在這裏做的如果不是完全明顯,這是我第一次問一個問題就在這裏,在事先我感謝所有幫助!

新 - 。12年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')    

回答

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而不起作用,因爲只有一行將滿足所有必要條件。 min(或max)只是因爲group by而必需的:我們通過選擇非空值將兩行合併爲一行。
  • 有關rank()的信息,請參閱its documentation on MSDN
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') 
+0

也許你打算通過'job'添加到每個子查詢的分組。 –

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 
; 

您可以此查詢它at SQL Fiddle