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 |
|
Ken Blum
Constraint Violating Yak Guru
383 Posts |
Posted - 2003-03-05 : 11:26:39
|
I have this rather lenghty SPROC that creates a dynamic SQL-Select statement and EXECUTE()'s it. This works fine and ends up creating a "ResultSet" (or Cursor) that contains multiple records for multiple ClientCodes. After this I need to select the last record for each client from that ResultSet returning the NewResultSet... SELECT * FROM ResultSet AS TA WHERE TrackDataIDKEY = (Select MAX(TrackDataIDKEY) FROM ResultSet AS TB WHERE TB.ClientCode = TA.ClientCode) How do I do this? Can I somehow use DECLARE CURSOR on the dynamic SQL-Select? Here is the SPROC code... CREATE PROCEDURE Get_TrackData_By_Company@ClientCode nchar(8), -- Return records related to a certain unique Client Code only. Blank = All@SerialNumber nchar(20), -- Return records related to a certain unique Machine Serial Number only. Blank = All@Start_DateTime nchar(22), -- Beginning Date/Time Range. Required Parameter@End_DateTime nchar(22), -- Ending Date/Time Range. Required Parameter.@Region nchar(2), -- Return records related to a specific Region (N,E,S,W,NE,SE,NW,NE,F (Foreign)). Blank = All@ErrorLevel nchar, -- Return Records for selected Error Level (0=Green, 1=Yellow, 2=Red)@HighestError nchar, -- Return Highest ErrorLevel (Logical True/False)@LastError nchar, -- Return Last Error Only (Logical True/False)@ClearedErrors nchar -- 0 = Ignore "Cleared" setting, 1 = Return "Uncleared" Errors only, 2 = Return "Cleared" Errors OnlyASDECLARE @SQLString nvarchar(4000)SET @SqlString = 'Select TrackData.TrackDataIDKey, Clients.ClientCode,Clients.Company,Clients.Addr1,Clients.Addr2,Clients.City,Clients.State,Clients.Zip, Clients.Region,Clients.Contact,Clients.Contact_Phone,Clients.ServiceMgr,Clients.ServicePhone, Machines.SerialNumber, Machines.Machine_Type,MachineTypes.Description AS Machine_Type_Desc, Versions.Version as FirmWare_Version, TrackData.ErrorCode, ErrorCodes.Description AS Error_Description, ErrorCodes.ErrorLevel, TrackData.Time_Stamp, TrackData.Text AS Client_Text, TrackData.Cleared_By, TrackData.Cleared_On, TrackData.ErrorLevel AS Current_Error_Level'SET @SQLString = @SQLString + ' FROM TRACKDATA LEFT JOIN CLIENTS ON Clients.ClientCode = TrackData.ClientCode LEFT JOIN MACHINES ON Machines.SerialNumber = TrackData.SerialNumber LEFT JOIN MACHINETYPES ON Machines.Machine_Type = MachineTypes.Machine_Type LEFT JOIN ERRORCODES ON ErrorCodes.Machine_Type = MachineTypes.Machine_Type AND ErrorCodes.ErrorCode = TrackData.ErrorCode LEFT JOIN VERSIONS ON Versions.VersionIDKey = Machines.Firmware_Code ' SET @SQLString = @SQLString + ' WHERE Machines.Active = 1 AND Time_Stamp BETWEEN '+CHAR(39)+@Start_DateTime+CHAR(39) +' AND '+CHAR(39)+@End_DateTime+CHAR(39)IF LEN(@ClientCode) > 0 SET @SQLString = @SQLString + ' AND TrackData.ClientCode = '+CHAR(39)+@ClientCode+CHAR(39)IF LEN(@SerialNumber) > 0 SET @SQLString = @SQLString + ' AND TrackData.SerialNumber = '+CHAR(39)+@SerialNumber+CHAR(39)IF LEN(@Region) > 0 SET @SQLString = @SQLString + ' AND Clients.Region = '+CHAR(39)+@Region+CHAR(39)IF @ErrorLevel > '0' SET @SQLString = @SQLString + ' AND TrackData.ErrorLevel >= '+@ErrorLevelIF @ClearedErrors > '0' BEGIN SET @SQLString = @SQLString + ' AND LEN(LTRIM(TrackData.Cleared_By)) ' IF @ClearedErrors = '1' SET @SQLString = @SQLString + ' = 0 OR TrackData.Cleared_By IS NULL' ELSE SET @SQLString = @SQLString + ' > 0' ENDSET @SQLString = @SQLString + ' ORDER BY Clients.Company, Clients.ClientCode, Trackdata.Time_Stamp DESC'PRINT @SQLString--PRINT LEN(@SQLString)EXECUTE(@SqlString)GO Thanks in advance!Ken |
|
|
Page47
Master Smack Fu Yak Hacker
2878 Posts |
Posted - 2003-03-05 : 11:38:50
|
| Take a look at the INSERT...EXEC...syntax.Jay White{0} |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2003-03-05 : 11:41:35
|
| Why is dynamic SQL being used?Why not:Select TrackData.TrackDataIDKey, Clients.ClientCode,Clients.Company,Clients.Addr1,Clients.Addr2,Clients.City,Clients.State,Clients.Zip, Clients.Region,Clients.Contact,Clients.Contact_Phone,Clients.ServiceMgr,Clients.ServicePhone, Machines.SerialNumber, Machines.Machine_Type,MachineTypes.Description AS Machine_Type_Desc, Versions.Version as FirmWare_Version, TrackData.ErrorCode, ErrorCodes.Description AS Error_Description, ErrorCodes.ErrorLevel, TrackData.Time_Stamp, TrackData.Text AS Client_Text, TrackData.Cleared_By, TrackData.Cleared_On, TrackData.ErrorLevel AS Current_Error_Level'FROM TRACKDATA LEFT JOIN CLIENTS ON Clients.ClientCode = TrackData.ClientCode LEFT JOIN MACHINES ON Machines.SerialNumber = TrackData.SerialNumber LEFT JOIN MACHINETYPES ON Machines.Machine_Type = MachineTypes.Machine_Type LEFT JOIN ERRORCODES ON ErrorCodes.Machine_Type = MachineTypes.Machine_Type AND ErrorCodes.ErrorCode = TrackData.ErrorCode LEFT JOIN VERSIONS ON Versions.VersionIDKey = Machines.Firmware_Code WHERE Machines.Active = 1 AND Time_Stamp BETWEEN @Start_DateTime AND @End_DateTimeAND TrackData.ClientCode Like ISNULL(@ClientCode, '%')AND TrackData.SerialNumber LIKE ISNULL(@SerialNumber, '%')AND Clients.Region LIKE ISNULL(@Region,'%')AND TrackData.ErrorLevel >= @ErrorLevel-- not sure about your "cleared errors" criteria-- explain that part in english and I can translate for youORDER BY Clients.Company, Clients.ClientCode, Trackdata.Time_Stamp DESCor something along those lines, with minor changes?- Jeff |
 |
|
|
Ken Blum
Constraint Violating Yak Guru
383 Posts |
Posted - 2003-03-05 : 12:10:12
|
| Thanks Jeff.I think you are right about dropping dynamic. It never occured to me to use ISNULL like that. I will try it.The "ClearedErrors" parameter refers to a Cleared_By char field that may contain null, blank, or some text. If ClearedErrors is '0' then it's supposed to ignore the value, if ClearedErrors is '1' then it should only select records that the field value is blank or null, or if ClearedErrors is '2' then it should only select field values that contain text.Still, how can I do an additional select on this resultset?Thanks, Ken |
 |
|
|
Ken Blum
Constraint Violating Yak Guru
383 Posts |
Posted - 2003-03-05 : 14:53:07
|
Ok, I got rid of the dynamic. Now, how can I select the top record from each client when @LastError parameter = 1 from the resulting recordset? Here's the new code... CREATE PROCEDURE Get_TrackData_By_Company@ClientCode nchar(8), -- Return records related to a certain unique Client Code only. Blank = All@SerialNumber nchar(20), -- Return records related to a certain unique Machine Serial Number only. Blank = All@Start_DateTime nchar(22), -- Beginning Date/Time Range. Required Parameter@End_DateTime nchar(22), -- Ending Date/Time Range. Required Parameter.@Region nchar(2), -- Return records related to a specific Region (N,E,S,W,NE,SE,NW,NE,F (Foreign)). Blank = All@ErrorLevel tinyint, -- Return Records for selected Error Level (0=Green, 1=Yellow, 2=Red)@HighestError tinyint, -- Return Highest ErrorLevel (Logical True/False)@LastError tinyint, -- Return Last Error Only (Logical True/False)@ClearedErrors tinyint -- 0 = Ignore “Cleared” setting, 1 = Return “Uncleared” Errors only, 2 = Return “Cleared” Errors OnlyASDECLARE @vClientCode varchar(8), @vSerialNumber varchar(20), @vRegion varchar(2)SET @ClientCode = ISNULL(@ClientCode,SPACE(8))SET @vClientCode = '%'IF @ClientCode != SPACE(8) SET @vClientCode = ISNULL(@ClientCode,'%')SET @SerialNumber = ISNULL(@SerialNumber,SPACE(20))SET @vSerialNumber = '%'IF @SerialNumber != SPACE(20) SET @vSerialNumber = ISNULL(@SerialNumber,'%')SET @Region = ISNULL(@Region,SPACE(2))SET @vRegion = '%'IF @Region != SPACE(2) SET @vRegion = ISNULL(@Region,'%')Select TrackData.TrackDataIDKey, Clients.ClientCode,Clients.Company,Clients.Addr1,Clients.Addr2,Clients.City,Clients.State,Clients.Zip, Clients.Region,Clients.Contact,Clients.Contact_Phone,Clients.ServiceMgr,Clients.ServicePhone, Machines.SerialNumber, Machines.Machine_Type,MachineTypes.Description AS Machine_Type_Desc, Versions.Version as FirmWare_Version, TrackData.ErrorCode, ErrorCodes.Description AS Error_Description, ErrorCodes.ErrorLevel, TrackData.Time_Stamp, TrackData.Text AS Client_Text, TrackData.Cleared_By, TrackData.Cleared_On, TrackData.ErrorLevel AS Current_Error_LevelFROM TRACKDATA LEFT JOIN CLIENTS ON Clients.ClientCode = TrackData.ClientCode LEFT JOIN MACHINES ON Machines.SerialNumber = TrackData.SerialNumber LEFT JOIN MACHINETYPES ON Machines.Machine_Type = MachineTypes.Machine_Type LEFT JOIN ERRORCODES ON ErrorCodes.Machine_Type = MachineTypes.Machine_Type AND ErrorCodes.ErrorCode = TrackData.ErrorCode LEFT JOIN VERSIONS ON Versions.VersionIDKey = Machines.Firmware_Code WHERE Machines.Active = 1 AND Time_Stamp BETWEEN @Start_DateTime AND @End_DateTime AND TrackData.ClientCode LIKE @vClientCode AND TrackData.SerialNumber LIKE @vSerialNumber AND Clients.Region LIKE @vRegion AND TrackData.ErrorLevel >= @ErrorLevel AND (@ClearedErrors = 0 OR (@ClearedErrors = 1 AND TrackData.Cleared_On IS NULL) OR (@ClearedErrors = 2 AND TrackData.Cleared_On IS NOT NULL))ORDER BY Clients.Company, Clients.ClientCode, Trackdata.Time_Stamp DESCGO |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2003-03-05 : 15:17:06
|
| So, I think what you are saying if @LastError = 1, then return only records where TrackData.Time_Stamp is the max for each client?Add this to your WHERE clause:AND ((@LastError = 0) OR TrackData.Time_Stamp = (SELECT Max(Time_stamp) FROM TrackData TD WHERE TD.ClientCode = Clients.ClientCode))- JeffEdited by - jsmith8858 on 03/05/2003 15:17:40 |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2003-03-05 : 15:19:55
|
Also: note that this line in your criteriaAND Clients.Region LIKE @vRegion is negating the LEFT OUTER JOIN from trackdata to clients because that criteria does not allow for Clients.Region to be null. (When I say negating I mean it is making it an INNER JOIN.)- JeffEdited by - jsmith8858 on 03/05/2003 15:23:34 |
 |
|
|
Ken Blum
Constraint Violating Yak Guru
383 Posts |
Posted - 2003-03-06 : 09:31:11
|
| Excellent! That is exactly what I was looking for.Thanks so much Jeff!Ken |
 |
|
|
Ken Blum
Constraint Violating Yak Guru
383 Posts |
Posted - 2003-03-06 : 10:01:45
|
| Just one more thing Jeff, what if I want to select the last highest error? Sometimes these will not be the same TrackData record.I have code like this now...Select TrackData.TrackDataIDKey, Clients.ClientCode,Clients.CorpCode,Clients.Company,Clients.Addr1,Clients.Addr2,Clients.City,Clients.State,Clients.Zip, Clients.Region,Clients.Contact,Clients.Contact_Phone,Clients.ServiceMgr,Clients.ServicePhone, Machines.SerialNumber, Machines.Machine_Type,MachineTypes.Description AS Machine_Type_Desc, Versions.Version as FirmWare_Version, TrackData.ErrorCode, ErrorCodes.Description AS Error_Description, ErrorCodes.ErrorLevel, TrackData.Time_Stamp, TrackData.Text AS Client_Text, TrackData.Cleared_By, TrackData.Cleared_On, TrackData.ErrorLevel AS Current_Error_LevelFROM TRACKDATA LEFT JOIN CLIENTS ON Clients.ClientCode = TrackData.ClientCode LEFT JOIN MACHINES ON Machines.SerialNumber = TrackData.SerialNumber LEFT JOIN MACHINETYPES ON Machines.Machine_Type = MachineTypes.Machine_Type LEFT JOIN ERRORCODES ON ErrorCodes.Machine_Type = MachineTypes.Machine_Type AND ErrorCodes.ErrorCode = TrackData.ErrorCode LEFT JOIN VERSIONS ON Versions.VersionIDKey = Machines.Firmware_Code WHERE Clients.Active = 1 AND Machines.Active = 1 AND Time_Stamp BETWEEN @Start_DateTime AND @End_DateTime AND TrackData.ClientCode LIKE @vClientCode AND TrackData.SerialNumber LIKE @vSerialNumber AND Clients.Region LIKE @vRegion AND TrackData.ErrorLevel >= @ErrorLevel AND (@ClearedErrors = 0 OR (@ClearedErrors = 1 AND TrackData.Cleared_On IS NULL) OR (@ClearedErrors = 2 AND TrackData.Cleared_On IS NOT NULL)) AND ((@LastError = 0) OR TrackData.Time_Stamp = (SELECT MAX(Time_Stamp) FROM TrackData TD WHERE TD.ClientCode = Clients.ClientCode)) AND ((@HighestError = 0) OR TrackData.ErrorLevel = (SELECT MAX(ErrorLevel) FROM TrackData TD WHERE TD.ClientCode = Clients.ClientCode)) ORDER BY Clients.Company, Clients.ClientCode, Trackdata.Time_Stamp DESCGO |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2003-03-06 : 11:50:11
|
| Add:TrackData.TimeStamp = (SELECT MAX(TimeStamp) FROM TrackData)- Jeff |
 |
|
|
Ken Blum
Constraint Violating Yak Guru
383 Posts |
Posted - 2003-03-07 : 11:02:41
|
| I already have that in there. The problem is this..TrackDataRecordID ClientCode Time_Stamp Error_Level505 TEST 1 3/1/03 11:00 2492 TEST 1 3/1/03 10:00 3480 TEST 1 3/1/03 09:00 3This would result in nothing selected, because the MAX(Time_Stamp) would be for record 505, and the MAX(Error_Level) would be for record 492.Also, there is another machines parent table to TrackData. How can I select all of the machines along with their "last highest error"? I need all of the machines listed regardless if they have a child record or not, so I am think Left Outer Join. However when I use a WHERE to select the Last Highest Error that negates my LEFT OUTER JOIN. How do I get around that?Thanks again... |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2003-03-07 : 11:19:04
|
| Try adding the error level criteria to that subquery.TrackData.TimeStamp = (SELECT MAX(TimeStamp) FROM TrackData WHERE TrackData.ErrorLevel >= @ErrorLevel )As for the other deal with all possible machines, I will get back to you on that one. I think your entire query needs to be restructured and parts moved into a subquery.- Jeff |
 |
|
|
Ken Blum
Constraint Violating Yak Guru
383 Posts |
Posted - 2003-03-07 : 13:11:57
|
| Thanks Jeff. This works as long as the TrackData child table has data... [code]CREATE PROCEDURE Get_Machines @ActiveOnly tinyintAS Select Machines.SerialNumber,Machines.Machine_Type,MachineTypes.Description AS Machine_Type_Desc, Versions.Version as FirmWare_Version,Machines.ClientCode, Clients.CorpCode,Clients.Company,Clients.Addr1,Clients.Addr2,Clients.City,Clients.State,Clients.Zip, Clients.Region,Clients.Contact,Clients.Contact_Phone,Clients.ServiceMgr,Clients.ServicePhone, TrackData.TrackDataIDKey,TrackData.Time_Stamp,TrackData.ErrorLevelFROM MACHINES LEFT OUTER JOIN MACHINETYPES ON MachineTypes.Machine_Type = Machines.Machine_Type LEFT OUTER JOIN VERSIONS ON Versions.VersionIDKey = Machines.Firmware_Code LEFT OUTER JOIN CLIENTS ON Clients.ClientCode = Machines.ClientCode LEFT OUTER JOIN TrackData ON TrackData.SerialNumber = Machines.SerialNumber WHERE (@ActiveOnly = 0 OR Machines.Active = 1) AND -- Get Last Highest Uncleared Error TrackData.TrackDataIDKey IN(SELECT TOP 1TrackDataIDKey From TrackData TM WHERE TM.SerialNumber = Machines.SerialNumber AND TM.Cleared_On IS NULL ORDER BY TM.ErrorLevel DESC, TM.Time_Stamp DESC)ORDER BY MACHINES.SerialNumberGO [/code |
 |
|
|
|
|
|
|
|