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最小操作
のオペコード: 研磨
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  

そのため、オペコードを追加しようとしても機能せず、あらゆる種類の重複値を取得し始めました。これは私が書いたものです:

(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-21-12

助けてくれてありがとう!両方の提案を試しましたが、どちらも希望どおりの結果を得ることができませんでした。しかし、それぞれの答えは、最終的に必要なものを手に入れるのに必要なものにたどり着くのに役立ちました。これは私の最初の質問なので、どの回答を解決策としてマークするまで何をすべきかわかりませんか? 私が言ったように、両方の答えが私を大いに助けてくれました. これにさらに取り組んだ後、私は自分の質問を明確にするために一生懸命努力しましたが、戻ってみると、どうすれば物事をもっとうまく表現できたのかがわかります. 繰り返しますが、私はすべての助けに非常に感謝しており、将来より良い質問をすることを楽しみにしています.
ちなみに、これが最終的に動作したコードです。

 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

1 つのアプローチを次に示します。

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行目では、1 つの行だけがすべての必要な基準を満たすため、それぞれminを変更しても効果はありません。max(minまたはmax) が必要なのは、group bynull 以外の値を選択して 2 つの行を 1 つに結合するためです。
  • の詳細については、 MSDN のドキュメントをrank()参照してください。
于 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 に答える