Here is a sample of my data and what I would like to see:
JOB OPSEQ OPCOMPLETE OPCODE
100 1 yes pull
100 2 yes weld
100 3 no grind
100 4 no machine
100 5 no asmbl
So I want to select the min(opseq) where opcomplete=no and the max(opseq) where opcomplete=yes, as well as the opcode of the min and max opseq's. In this example that would be:
min(opseq):3
opcode of min op: grind
max(opseq): 2
opcode of max op: weld
The reason I am looking for this is to get the opcode of the smallest opseq that is NOT complete.
I got the min and max opseqs to work great. This is what I had:
(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
So when I tried to get my opcodes added in, it didn't work, and I started gettings all kinds of duplicate values. This is what I wrote:
(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
Here is my entire code as it stands at the moment (with the opcodes pulling in all the duplicate values:
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')
I hope this all makes sense what I am trying to do here. If it isn't completely obvious this is my first time asking a question on here. In advance I appreciate all the help!!!
New - 12-21-12
Thank you both for your help! I tried both of your suggestions, but couldn't get either one to get the exact results I wanted. But each answer helped me get to what it eventually took to get what I needed. Since this is my first question, I don't know what I should do as far as marking which answer as a solution? Like I said, both answers helped me out a lot, and I think that the reason I couldn't get the results I wanted out of them is soley my fault. After working on this more, I realized that even though I tried very hard to be clear in my question, as I go back I see how I could have worded things much better. Again, I appreciate all the help very much, and I look forward to asking better questions in the future!
By the way, this is the code that worked in the end.
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')
Here is one approach:
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
;
Notes:
min
can be changed to max
with no effect, since only one row will meet all the necessary criteria. The min
(or max
) is only necessary because of the group by
: we're combining two rows into one by selecting the non-null value.rank()
, see its documentation on MSDN.I think this is a lot easier than you are making it, as long as OPSEQ is a unique value:
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')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With