Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
X002548
Not Just a Number
15586 Posts |
Posted - 2003-10-17 : 11:06:18
|
Now it's my turn...remebering all of the nonsense with the 1st10, last 10, MIDDLE 10!All well and good...But if I have a nice normalized tableCREATE TABLE myTable99 (EmpId Int, ContractNum char(6))GOI've been tasked with populating...CREATE TABLE myTable00 (EmpId Int, ContractNum1 char(6), ContractNum2 char(6), ContractNum3 char(6))GOAnd have been give the green light that the results can be arbitrary (like the first 3 ordered by contract number). Only if they have a contract number. If they have 1, I need to supply space.Now I want to do this without a cursor, and my first shot, I found the 1st distinct byte and left joined to it...one per type...but if they all had the same type, then I would only populate 1 column, and I would need to fill it with three..Here's some sample data...I'll post the code I took a shot at...but it's wrong as a mentioned above. Any ideas?INSERT INTO myTable99 (EmpId, ContractNum)SELECT 1, 'ABCD56' UNION ALLSELECT 2, 'AB12EF' UNION ALLSELECT 3, 'QWERTY' UNION ALLSELECT 4, NULL UNION ALLSELECT 5, 'ABZXEF' UNION ALLSELECT 5, 'LMNOPQ' UNION ALLSELECT 5, 'QWESEY' UNION ALLSELECT 6, 'AOBWEF' UNION ALLSELECT 6, 'LMTWEP' UNION ALLSELECT 6, 'SWESTY' UNION ALLSELECT 6, 'ZOB2EF' UNION ALLSELECT 6, 'DMT3EP' UNION ALLSELECT 6, 'JWES4Y' UNION ALLGODon't freak it's DB2.."||" = +..but the rest is pretty similar..SELECT PERSON_ID, ID_TYPE_CD , SUBSTR(CONTRACT_NUMS,1,6) AS CONTRACT_NUM1 , SUBSTR(CONTRACT_NUMS,7,6) AS CONTRACT_NUM2 , SUBSTR(CONTRACT_NUMS,13,6) AS CONTRACT_NUM3 , SUBSTR(CONTRACT_NUMS,19,6) AS CONTRACT_NUM4 , SUBSTR(CONTRACT_NUMS,25,6) AS CONTRACT_NUM5 , SUBSTR(CONTRACT_NUMS,31,6) AS CONTRACT_NUM6 , SUBSTR(CONTRACT_NUMS,37,6) AS CONTRACT_NUM7 , SUBSTR(CONTRACT_NUMS,43,6) AS CONTRACT_NUM8 , SUBSTR(CONTRACT_NUMS,49,6) AS CONTRACT_NUM9 , SUBSTR(CONTRACT_NUMS,55,6) AS CONTRACT_NUM10 FROM ( SELECT A.PERSON_ID, A.ID_TYPE_CD , REPLACE( VALUE(B.CONTRACT_NUM1 ,' ') || VALUE(C.CONTRACT_NUM2 ,' ') || VALUE(D.CONTRACT_NUM3 ,' ') || VALUE(E.CONTRACT_NUM4 ,' ') || VALUE(F.CONTRACT_NUM5 ,' ') || VALUE(G.CONTRACT_NUM6 ,' ') || VALUE(H.CONTRACT_NUM7 ,' ') || VALUE(I.CONTRACT_NUM8 ,' ') || VALUE(J.CONTRACT_NUM9 ,' ') || VALUE(K.CONTRACT_NUM10,' ') ,' ','')||SPACE(60) AS CONTRACT_NUMS FROM PRU_REL A LEFT JOIN (SELECT PERSON_ID, ID_TYPE_CD, MAX(CONTRACT_NUM) AS CONTRACT_NUM1 FROM PRU_REL WHERE SUBSTR(CONTRACT_NUM,1,1) = 'Z' GROUP BY PERSON_ID, ID_TYPE_CD) AS B ON A.PERSON_ID = B.PERSON_ID AND A.ID_TYPE_CD = B.ID_TYPE_CD LEFT JOIN (SELECT PERSON_ID, ID_TYPE_CD, MAX(CONTRACT_NUM) AS CONTRACT_NUM2 FROM PRU_REL WHERE SUBSTR(CONTRACT_NUM,1,1) = '9' GROUP BY PERSON_ID, ID_TYPE_CD) AS C ON A.PERSON_ID = C.PERSON_ID AND A.ID_TYPE_CD = C.ID_TYPE_CD LEFT JOIN (SELECT PERSON_ID, ID_TYPE_CD, MAX(CONTRACT_NUM) AS CONTRACT_NUM3 FROM PRU_REL WHERE SUBSTR(CONTRACT_NUM,1,1) = '8' GROUP BY PERSON_ID, ID_TYPE_CD) AS D ON A.PERSON_ID = D.PERSON_ID AND A.ID_TYPE_CD = D.ID_TYPE_CD LEFT JOIN (SELECT PERSON_ID, ID_TYPE_CD, MAX(CONTRACT_NUM) AS CONTRACT_NUM4 FROM PRU_REL WHERE SUBSTR(CONTRACT_NUM,1,1) = '7' GROUP BY PERSON_ID, ID_TYPE_CD) AS E ON A.PERSON_ID = E.PERSON_ID AND A.ID_TYPE_CD = E.ID_TYPE_CD LEFT JOIN (SELECT PERSON_ID, ID_TYPE_CD, MAX(CONTRACT_NUM) AS CONTRACT_NUM5 FROM PRU_REL WHERE SUBSTR(CONTRACT_NUM,1,1) = '6' GROUP BY PERSON_ID, ID_TYPE_CD) AS F ON A.PERSON_ID = F.PERSON_ID AND A.ID_TYPE_CD = F.ID_TYPE_CD LEFT JOIN (SELECT PERSON_ID, ID_TYPE_CD, MAX(CONTRACT_NUM) AS CONTRACT_NUM6 FROM PRU_REL WHERE SUBSTR(CONTRACT_NUM,1,1) = '5' GROUP BY PERSON_ID, ID_TYPE_CD) AS G ON A.PERSON_ID = G.PERSON_ID AND A.ID_TYPE_CD = G.ID_TYPE_CD LEFT JOIN (SELECT PERSON_ID, ID_TYPE_CD, MAX(CONTRACT_NUM) AS CONTRACT_NUM7 FROM PRU_REL WHERE SUBSTR(CONTRACT_NUM,1,1) = '4' GROUP BY PERSON_ID, ID_TYPE_CD) AS H ON A.PERSON_ID = H.PERSON_ID AND A.ID_TYPE_CD = H.ID_TYPE_CD LEFT JOIN (SELECT PERSON_ID, ID_TYPE_CD, MAX(CONTRACT_NUM) AS CONTRACT_NUM8 FROM PRU_REL WHERE SUBSTR(CONTRACT_NUM,1,1) = '3' GROUP BY PERSON_ID, ID_TYPE_CD) AS I ON A.PERSON_ID = I.PERSON_ID AND A.ID_TYPE_CD = I.ID_TYPE_CD LEFT JOIN (SELECT PERSON_ID, ID_TYPE_CD, MIN(CONTRACT_NUM) AS CONTRACT_NUM9 FROM PRU_REL WHERE SUBSTR(CONTRACT_NUM,1,1) = 'Z' GROUP BY PERSON_ID, ID_TYPE_CD) AS J ON A.PERSON_ID = J.PERSON_ID AND A.ID_TYPE_CD = J.ID_TYPE_CD LEFT JOIN (SELECT PERSON_ID, ID_TYPE_CD, MIN(CONTRACT_NUM) AS CONTRACT_NUM10 FROM PRU_REL WHERE SUBSTR(CONTRACT_NUM,1,1) = '9' GROUP BY PERSON_ID, ID_TYPE_CD) AS K ON A.PERSON_ID = K.PERSON_ID AND A.ID_TYPE_CD = K.ID_TYPE_CD WHERE A.CONTRACT_NUM <> ' ') AS XXX ; Brett8-) |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2003-10-17 : 12:39:53
|
i assume the pk of the table is empid/contract ?If so, just calc the "rank" of each contract per employee. then pivot on the rank, using the first 3.i.e.,start with this:SELECT empid, contract, (select count(*) from myTable99 where a.empid = myTable99.empID and a.contract <= myTable99.contract) as RankFROM myTable99 a and then do a simple cross tab:select empID, MAX(When rank=1 then contract else ' ' end) as Contract1, MAX(When rank=2 then contract else ' ' end) as Contract2, MAX(When rank=3 then contract else ' ' end) as Contract3FROM (above SQL) aWHERE Rank <= 3GROUP BY EmpID something like that.- Jeff |
 |
|
|
Stoad
Freaky Yak Linguist
1983 Posts |
Posted - 2003-10-17 : 13:32:06
|
| OMG,now my head hurts... |
 |
|
|
X002548
Not Just a Number
15586 Posts |
Posted - 2003-10-17 : 13:50:32
|
Jeff,awesome...some tweaking though and it works like a champ SELECT empID , MAX(CASE When rank=1 then contractNum else ' ' end) as Contract1 , MAX(CASE When rank=2 then contractNum else ' ' end) as Contract2 , MAX(CASE When rank=3 then contractNum else ' ' end) as Contract3 FROM ( SELECT empid , contractNum , (SELECT count(*) FROM myTable99 b WHERE a.empid = b.empID AND a.contractNum <= b.contractNum) as Rank FROM myTable99 a) a WHERE Rank <= 3GROUP BY EmpID However it doesn't work in DB2...I tested, and I don't it supports SELECT (SELECT...syntax yet..I wonder if I can turn that part in to a join...Brett8-) |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2003-10-17 : 13:55:29
|
Yes! you can. in fact, that's how I used to always do these queries before I became fairly proficient with T-SQL.something like this:Select A.empID, A.Contract, count(*) as RankFROM myTable99 AINNER JOIN myTable99 BON A.empID = B.EmpID and A.Contract >= B.ContractGROUP BY a.empID, a.Contract - Jeff |
 |
|
|
X002548
Not Just a Number
15586 Posts |
Posted - 2003-10-17 : 14:03:34
|
Wow.... SELECT A.empID, A.ContractNum, count(*) as Rank FROM myTable99 AINNER JOIN myTable99 B ON A.empID = B.EmpID AND A.ContractNum >= B.ContractNum GROUP BY a.empID, a.ContractNum An I image to flip it on it's side it's a self join?Is there an easier way?empID ContractNum Rank ----------- ----------- ----------- 2 AB12EF 11 ABCD56 15 ABZXEF 16 AOBWEF 16 DMT3EP 26 JWES4Y 35 LMNOPQ 26 LMTWEP 43 QWERTY 15 QWESEY 36 SWESTY 56 ZOB2EF 6 Brett8-) |
 |
|
|
X002548
Not Just a Number
15586 Posts |
Posted - 2003-10-17 : 14:48:55
|
| I figure I'll just drop it all in to a temp table...and away we go...THANKS JEFF!Brett8-) |
 |
|
|
|
|
|
|
|