2012-12-20 14 views
6

Oto próbka moich danych i co chciałbym zobaczyć:Getting inne wartości dziedzinie linii z MIN/MAX wartości

JOB OPSEQ OPCOMPLETE OPCODE 

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

Więc chcę zaznaczyć min (opseq) gdzie opcomplete = no i max (opseq) gdzie opcomplete = yes, a także kod operacyjny min i max opseq. W tym przykładzie byłoby:
min (opseq) 3
kodu operacji min op: mielenia
max (opseq): 2 kodu operacji max op: spoiny

Powodem szukam jest aby uzyskać kod operacyjny najmniejszego opseq, który NIE jest kompletny.
Mam min i max opseqs do świetnej pracy. To co miałem:

(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 

Więc gdy próbowałem się dostać moje rozkazy dodaje się, że nie działa, a ja zacząłem gettings wszelkiego rodzaju duplikatów wartości. To co napisałem:

(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 

Tu jest mój cały kod, gdyż stoi w tej chwili (z opcodes ciągnięcie we wszystkich zduplikowanych wartości:

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

Mam nadzieję, że to wszystko ma sens, co ja staram się zrobić tutaj Jeśli nie jest to zupełnie oczywiste, jest to mój pierwszy raz zadaje pytanie tutaj z góry doceniam wszelką pomoc !!!

New -.. 12-21-12

podziękowaniem Siema zarówno dla twojej pomocy! Próbowałem obu twoich sugestii, ale nie udało mi się uzyskać żadnego z nich, by uzyskać dokładnie takie wyniki, jakie chciałem. Ale każda odpowiedź pomogła mi uzyskać to, czego ostatecznie potrzebowałem, aby uzyskać to, czego potrzebowałem. Ponieważ to jest moje pierwsze pytanie, nie wiem, co powinienem zrobić, jeśli chodzi o zaznaczenie, która odpowiedź jest rozwiązaniem? Tak jak powiedziałem, obie odpowiedzi bardzo mi pomogły i myślę, że powodem, dla którego nie mogłem osiągnąć pożądanych rezultatów, jest moja wina. Pracując nad tym więcej, zdałem sobie sprawę, że chociaż bardzo się starałem, aby było jasne w moim pytaniu, kiedy wracam, widzę, jak mogłem znacznie lepiej opisać rzeczy. Ponownie doceniam całą pomoc i czekam z niecierpliwością na zadawanie lepszych pytań w przyszłości!
Nawiasem mówiąc, to jest kod, który działał na końcu.

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

Odpowiedz

5

Oto jeden sposób:

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 
; 

Uwagi:

  • nie testowane.
  • w wierszach 2 – 5, każdy min można zmienić na max bez efektu, ponieważ tylko jeden wiersz spełnia wszystkie niezbędne kryteria. Numer min (lub max) jest potrzebny tylko z powodu group by: łączymy dwa wiersze w jeden, wybierając wartość inną niż null.
  • , aby uzyskać informacje na temat rank(), patrz its documentation on MSDN.
3

myślę, że to jest o wiele łatwiejsze niż robisz to, jak długo OPSEQ to unikalna wartość:

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

Być może zamierzałeś dodać grupowanie według 'zadania' do każdego z podzapytań. –

1

Zakładając, że używasz SQL Server 2005 lub nowszy, można również rozważyć użycie CROSS APPLY, tak:

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 
; 

można to zapytanie to at SQL Fiddle.

Powiązane problemy