Working my way into SQL from Access. Think I might have the hang of the basics, but would really appreciate a sanity check. The stored procedure listed below works, but I can't help but think there is a better way to do this.
Gist of what I'm doing:
I need aggregate error data for each satellite in tblSatellite.
-Satellite code, name, etc.
-Count of number of errors over a given frame of time
-The Problem Type with the most errors for each satellite over that given frame of time, which may be more than one record if two Max & Count records equal each other. Sticky part here, basically doing a Max of Count.
-I filter out records with fkResolutionTypeID = 8 or 12 for business reasons.
Thoughts and problems:
-Maybe building a temp table with just the results of the innermost query would be beneficial? One table query, then further queries off the table variable. Right now the below query hits tblErrorList 3 times. Also, for some reason Access Projects (which I'm using right now as the primary client app), don't like table variables. Just returns empty record set.
-I could separate out the Max part of this as a separate procedure or function. ie, client app calls the SQL server to get the max problem type for each satellite separately. Questionable efficiency? My thinking (please correct me), is that fewer queries typically equals better performance.
-I could also forget all this SQL garbage and go back to drawing on my etch-a-sketch.
Any ideas are much appreciated!
Tables with used fields:
tblErrorList
-pkErrorID (Primary key)
-fkSatelliteID (foreign key to tblSatellite)
-DateOfService
-fkProblemTypeID (foreign key to tlkpProblemTypes)
-fkResolutionTypeID (foreign key, used here just to filter out 'non' problems)
tblSatellite
-pkSatelliteID
-SatelliteCode
-fkManagerID (foreign key to tlkpManager)
-NameOrLocation
tlkpProblemTypes
-pkProblemTypeID
-ProblemCode (description really)
tlkpManager
-pkManagerID
-ManagerName
Expand|Select|Wrap|Line Numbers
- CREATE PROCEDURE GetErrCountBySite_Type (@sDate AS SMALLDATETIME, @eDate AS SMALLDATETIME)
- AS
- SELECT tblSatellite.SatelliteCode, tblSatellite.NameOrLocation, tlkpManager.ManagerName, tlkpProblemTypes.ProblemCode, D.CountOfErrors
- FROM (SELECT TOP 100 PERCENT fkSatelliteID, MAX(CountOfErrors) AS maxcount
- FROM (SELECT TOP 100 PERCENT fkSatelliteID, fkProblemTypeID, COUNT(pkErrorID) AS CountOfErrors
- FROM dbo.tblErrorList
- WHERE (DateOfService >= CONVERT(DATETIME, @sDate, 102) AND DateOfService < CONVERT(DATETIME, DATEADD(d,1,@eDate), 102)) AND
- (fkResolutionTypeID IS NULL OR
- fkResolutionTypeID <> 8 AND fkResolutionTypeID <> 12)
- GROUP BY fkSatelliteID, fkProblemTypeID
- ORDER BY fkSatelliteID, fkProblemTypeID) C
- GROUP BY fkSatelliteID
- ORDER BY fkSatelliteID) A
- INNER JOIN
- (SELECT TOP 100 PERCENT fkSatelliteID, fkProblemTypeID, COUNT(pkErrorID) AS CountOfErrors
- FROM dbo.tblErrorList
- WHERE (DateOfService >= CONVERT(DATETIME, @sDate, 102) AND DateOfService < CONVERT(DATETIME, DATEADD(d,1,@eDate), 102)) AND
- (fkResolutionTypeID IS NULL OR
- fkResolutionTypeID <> 8 AND fkResolutionTypeID <> 12)
- GROUP BY fkSatelliteID, fkProblemTypeID
- ORDER BY fkSatelliteID, fkProblemTypeID) B
- ON B.fkSatelliteID=A.fkSatelliteID AND B.CountOfErrors=A.maxcount
- INNER JOIN
- (SELECT TOP 100 PERCENT fkSatelliteID, COUNT(pkErrorID) AS CountOfErrors
- FROM dbo.tblErrorList
- WHERE (DateOfService >= CONVERT(DATETIME, @sDate, 102) AND DateOfService < CONVERT(DATETIME, DATEADD(d,1,@eDate), 102)) AND
- (fkResolutionTypeID IS NULL OR
- fkResolutionTypeID <> 8 AND fkResolutionTypeID <> 12)
- GROUP BY fkSatelliteID
- ORDER BY fkSatelliteID) D
- ON D.fkSatelliteID=A.fkSatelliteID
- INNER JOIN
- dbo.tblSatellite
- ON tblSatellite.pkSatelliteID=A.fkSatelliteID
- INNER JOIN
- dbo.tlkpProblemTypes
- ON tlkpProblemTypes.pkProblemTypeID = B.fkProblemTypeID
- INNER JOIN
- dbo.tlkpManager
- ON tlkpManager.pkManagerID=tblSatellite.fkManagerID