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 |
|
liffey
Yak Posting Veteran
58 Posts |
Posted - 2004-08-05 : 11:44:46
|
| Table 1 contains "jobs" Table 2 contains job status entries (currently 6 per job)Job status is ranked by priority with a value indicating if thie status has been achieved.e.g.job # : status :rank : value (True/False)1 : logged : 1 : t1 : stage 1 complete : 2 : t1 : stage 2 complete : 3 : t1 : stage 3 complete : 4 : F1 : cancelled : 6 : t1 : completed : 5 : FWhat I need to do is select all rows from table 1 with the highest ranked status for each job from table 2.e.g.job #, - job details from table 1 -, highest ranked status from table 21, job details, cancelledHow can I achieve this?Any help appreciated.-dw |
|
|
spirit1
Cybernetic Yak Master
11752 Posts |
Posted - 2004-08-05 : 12:21:27
|
| select * from Table1 t1 inner join (select JobId, max(rank) as rank from Table2 group by JobId) as t2 on t1.JobId = t2.JobIdGo with the flow & have fun! Else fight the flow :) |
 |
|
|
liffey
Yak Posting Veteran
58 Posts |
Posted - 2004-08-09 : 06:51:53
|
| Thanks for the reply spirit1.I have been working on your suggestion but can't quite get what I want. My original post showed a sample of what I was trying to achieve. The code below is as near as I can get to what I want:SELECT t1.JobNumber, t1.StatusID AS JobStatusID, t2.StatusDescription, t2.PriorityFROM jobHeaders t1 INNER JOIN (SELECT jobStatus.JobNumber, jobStatus.StatusID AS StatusID, jobStatusList.StatusDescription, jobStatusList.Priority FROM jobStatus INNER JOIN jobStatusList ON jobStatus.StatusID = jobStatusList.StatusID WHERE (jobStatus.[Value] = 1)) t2 ON t1.JobNumber = t2.JobNumberThe result I get isJobNumber...JobStatusID...StatusDescription...Priority...04G01157....1.............Awaiting Check......9..........04G01157....1.............Job Printed.........8..........04G01157....1.............Parts Printed.......7..........04G01158....1.............Job Printed.........8..........04G01158....1.............Sending.............5..........My first problem is that I need to sort by jobNumber, Priority in order to get the lowest priority value for each job. The second problem is that I only want the item with the lowest Priority value, the rows with priority value of 7 and 5 in my sample above.The result I want is:JobNumber...JobStatusID...StatusDescription...Priority...04G01157....1.............Parts Printed.......7..........04G01158....1.............Sending.............5..........The lowest priority value is the highest stage of processing that the job has reached. (the current status at a given point in time)Is this possible or do I need to rethink my approach?Thanks for your help.-dw |
 |
|
|
liffey
Yak Posting Veteran
58 Posts |
Posted - 2004-08-09 : 07:27:08
|
| Getting closer to what I want. The code below shows JobNumber and Priority.How can I extend this to show StatusDescription as well?Is there a better way to achieve the same result?Recommend a good book?Thanks,-dwSELECT JobNumber, MIN(Priority) AS PriorityFROM (SELECT t1.JobNumber, t1.StatusID AS JobStatusID, t2.StatusDescription, t2.Priority FROM jobHeaders t1 INNER JOIN (SELECT jobStatus.JobNumber, jobStatus.StatusID AS StatusID, jobStatusList.StatusDescription, jobStatusList.Priority FROM jobStatus INNER JOIN jobStatusList ON jobStatus.StatusID = jobStatusList.StatusID WHERE (jobStatus.[Value] = 1)) t2 ON t1.JobNumber = t2.JobNumber) DERIVEDTBLGROUP BY JobNumber |
 |
|
|
spirit1
Cybernetic Yak Master
11752 Posts |
Posted - 2004-08-09 : 08:08:25
|
| and this doesn't work for you?SELECT JobNumber, MIN(Priority) AS Priority, StatusDescriptionFROM (SELECT t1.JobNumber, t1.StatusID AS JobStatusID, t2.StatusDescription, t2.PriorityFROM jobHeaders t1 INNER JOIN(SELECT jobStatus.JobNumber, jobStatus.StatusID AS StatusID, jobStatusList.StatusDescription, jobStatusList.PriorityFROM jobStatus INNER JOIN jobStatusList ON jobStatus.StatusID = jobStatusList.StatusIDWHERE (jobStatus.[Value] = 1)) t2 ON t1.JobNumber = t2.JobNumber) DERIVEDTBLGROUP BY JobNumber, StatusDescriptionbooks: http://www.sqlteam.com/store.aspGo with the flow & have fun! Else fight the flow :) |
 |
|
|
liffey
Yak Posting Veteran
58 Posts |
Posted - 2004-08-09 : 09:09:41
|
| Yes it shows the StatusDescription but returns rows for each Status not just the highest (lowest Priority value)The following returns 1 row as expected:SELECT JobNumber, MIN(Priority) AS PriorityFROM (SELECT t1.JobNumber, t1.StatusID AS JobStatusID, t2.StatusDescription, t2.Priority FROM jobHeaders t1 INNER JOIN (SELECT jobStatus.JobNumber, jobStatus.StatusID AS StatusID, jobStatusList.StatusDescription, jobStatusList.Priority FROM jobStatus INNER JOIN jobStatusList ON jobStatus.StatusID = jobStatusList.StatusID WHERE (jobStatus.[Value] = 1)) t2 ON t1.JobNumber = t2.JobNumber) DERIVEDTBLwhere jobnumber='04G01157'GROUP BY JobNumberorder by jobnumberAdding StatusDescription returns 4 rows - one for each status. In otherwords it overrides the "MIN" function:SELECT JobNumber, MIN(Priority) AS Priority, StatusDescriptionFROM (SELECT t1.JobNumber, t1.StatusID AS JobStatusID, t2.StatusDescription, t2.Priority FROM jobHeaders t1 INNER JOIN (SELECT jobStatus.JobNumber, jobStatus.StatusID AS StatusID, jobStatusList.StatusDescription, jobStatusList.Priority FROM jobStatus INNER JOIN jobStatusList ON jobStatus.StatusID = jobStatusList.StatusID WHERE (jobStatus.[Value] = 1)) t2 ON t1.JobNumber = t2.JobNumber) DERIVEDTBLwhere jobnumber='04G01157'GROUP BY JobNumber, StatusDescriptionorder by jobnumber |
 |
|
|
spirit1
Cybernetic Yak Master
11752 Posts |
Posted - 2004-08-09 : 09:32:46
|
| well without your table structure i can only guess, but it seems you only need one more join on the whole query...it would be useful if you post the table schem and sample data so we can simply run them through the QA.Go with the flow & have fun! Else fight the flow :) |
 |
|
|
liffey
Yak Posting Veteran
58 Posts |
Posted - 2004-08-09 : 12:20:35
|
| OK here we go:SQL Scripts to create 3 tables (I have only included relevant fields):if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[jobHeadersTest]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)drop table [dbo].[jobHeadersTest]GOCREATE TABLE [dbo].[jobHeadersTest] ( [id] [int] IDENTITY (1, 1) NOT NULL , [JobNumber] [varchar] (10) COLLATE Latin1_General_CI_AS NOT NULL , [StatusID] [int] NULL ) ON [PRIMARY]GOif exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[jobStatusListTest]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)drop table [dbo].[jobStatusListTest]GOCREATE TABLE [dbo].[jobStatusListTest] ( [StatusID] [int] IDENTITY (1, 1) NOT NULL , [StatusDescription] [varchar] (30) COLLATE SQL_Latin1_General_CP1_CI_AS NULL , [Priority] [int] NULL , [Timestamp] [timestamp] NULL , [ListOrder] [int] NULL ) ON [PRIMARY]GOif exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[jobStatusTest]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)drop table [dbo].[jobStatusTest]GOCREATE TABLE [dbo].[jobStatusTest] ( [id] [int] IDENTITY (1, 1) NOT NULL , [JobNumber] [varchar] (10) COLLATE Latin1_General_CI_AS NOT NULL , [StatusID] [int] NOT NULL , [Initials] [char] (4) COLLATE Latin1_General_CI_AS NULL , [TimeStamp] [timestamp] NULL , [Value] [bit] NOT NULL ) ON [PRIMARY]GOQueries:-- This does not give me what I want-- I only want one row returned with the lowest priority valueSELECT JobNumber, MIN(Priority) AS Priority, StatusDescriptionFROM (SELECT t1.JobNumber, t1.StatusID AS JobStatusID, t2.StatusDescription, t2.Priority FROM jobHeadersTest t1 INNER JOIN (SELECT jobStatusTest.JobNumber, jobStatusTest.StatusID AS StatusID, jobStatusListTest.StatusDescription, jobStatusListTest.Priority FROM jobStatusTest INNER JOIN jobStatusListTest ON jobStatusTest.StatusID = jobStatusListTest.StatusID WHERE (jobStatusTest.[Value] = 1)) t2 ON t1.JobNumber = t2.JobNumber) DERIVEDTBLwhere jobnumber='04G01157'GROUP BY JobNumber, StatusDescriptionorder by jobnumberResult04G01157 9 Awaiting Check04G01157 7 Parts Printed04G01157 5 Sending04G01157 8 Yellow Printed-- This gives me what I want without the description!!!SELECT JobNumber, MIN(Priority) AS PriorityFROM (SELECT t1.JobNumber, t1.StatusID AS JobStatusID, t2.StatusDescription, t2.Priority FROM jobHeadersTest t1 INNER JOIN (SELECT jobStatusTest.JobNumber, jobStatusTest.StatusID AS StatusID, jobStatusListTest.StatusDescription, jobStatusListTest.Priority FROM jobStatusTest INNER JOIN jobStatusListTest ON jobStatusTest.StatusID = jobStatusListTest.StatusID WHERE (jobStatusTest.[Value] = 1)) t2 ON t1.JobNumber = t2.JobNumber) DERIVEDTBLwhere jobnumber='04G01157'GROUP BY JobNumberorder by jobnumberResult04G01157 5What I want:04G01157 5 SendingTest Data:JobHeadersTest"id","JobNumber","StatusID"492,"04G01157",1JobStatusTest"id","JobNumber","StatusID","Initials","Value"2953,"04G01157",1,"EM ",True2954,"04G01157",2,"",False2955,"04G01157",3,"AB ",True2956,"04G01157",4,"3 ",True2957,"04G01157",5,"",False2958,"04G01157",6,"WEB ",True2959,"04G01157",7,"",False2960,"04G01157",8,"",FalseJobStatusList"StatusID","StatusDescription","Priority","ListOrder"1,"Awaiting Check",9,12,"On Hold",2,23,"Yellow Printed",8,34,"Parts Printed",7,45,"All Results Received",6,56,"Sending",5,67,"Sent to Accounts",3,78,"Cancelled",1,8JobHeadersTest links to JobStatus by JobNumberJobStatus links to JobStatusList by StatusIDThanks for all your help. I looked at the book list. Do you recommend any in particular for this type of work?-dw |
 |
|
|
spirit1
Cybernetic Yak Master
11752 Posts |
Posted - 2004-08-10 : 11:27:06
|
| try this select JST.JobNumber, JSLT.StatusDescription, JSLT.Priorityfrom @JobStatusTest JST inner join @jobStatusListTest JSLT on (JST.StatusID = JSLT.StatusID) and (JST.Value=1) inner join (select t1.JobNumber, min(Priority) as Priority from @JobStatusTest t1 inner join @jobStatusListTest t2 on (t1.StatusID = t2.StatusID) and (t1.Value=1) group by t1.JobNumber) JSLT2 on (JST.JobNumber = JSLT2.JobNumber) and (JSLT.Priority = JSLT2.Priority)where JST.jobnumber='04G01157'Go with the flow & have fun! Else fight the flow :) |
 |
|
|
spirit1
Cybernetic Yak Master
11752 Posts |
Posted - 2004-08-10 : 11:53:07
|
| Joe Celko's books are very good.Go with the flow & have fun! Else fight the flow :) |
 |
|
|
liffey
Yak Posting Veteran
58 Posts |
Posted - 2004-08-10 : 12:26:51
|
| Brilliant!Thanks for all your time and effort.Just one question. What is the significance of the @ before the table names in your query? I had to remove them to get it to run.-dw |
 |
|
|
spirit1
Cybernetic Yak Master
11752 Posts |
Posted - 2004-08-10 : 12:35:28
|
| i didn't want to create tables in my db so i used table variables. i just forgot to delete them.i would have posted the solution before but i didn't have the time...hope it works ok, and glad i could help.Go with the flow & have fun! Else fight the flow :) |
 |
|
|
|
|
|
|
|