Rewrite tsql select statement without sub-sub selects
I'd like to rewrite the following select statement without the sub selects; while it works at the moment as it is it only works if there's data, when one of the sub selects doesn't return data I get an error
Each GROUP BY expression must contain at least one column that is not an outer reference.
This is the select:
SELECT COUNT(DISTINCT ( PROMSID )) AS Volume ,
( SELECT CAST(CAST(COUNT(DISTINCT ( PROMSID )) AS DECIMAL(8, 2))
/ ( SELECT COUNT(DISTINCT RES.Branch)
FROM tblPROMsExportSummary AS PES
INNER JOIN TVF_GetRelevantScorecards(@ProcedureID, 82, @StartDate, @EndDate) AS RES ON RES.PROMSID = PES.PROMSID
INNER JOIN tblUploadedScorecards AS UPL ON PES.PROMSID = UPL.PEMSID
WHERE RES.[Month] = TVF.MonthValue
GROUP BY TVF.MonthValue
) AS DECIMAL(8, 2)) AS PCTAverage
FROM #RelevantSummaryPCT AS PCT
WHERE PCT.[Month] = TVF.[MonthValue]
GROUP BY TVF.[MonthValue]
) AS PCTAverage ,
TVF.ShortMonth AS [Month]
FROM #RelevantSummary AS RS
RIGHT OUTER JOIN TVF_Months(@StartDate, @EndDate) AS TVF ON TVF.MonthValue = RS.[Month]
GROUP BY TVF.[MonthName] ,
TVF.[MonthValue] ,
TVF.ShortMonth ,
TVF.DisplayOrder
ORDER BY TVF.DisplayOrder
What I am looking to achieve is a a single set of data from 2 te开发者_如何转开发mp tables which store results for different levels of reporting. The Volume column is the volume of results for 'my group' and the PCTAverage is the volume of results across all groups. The selects for those 2 temp tables:
SELECT DISTINCT
PES.FKProcedureID ,
PES.PROMSID ,
UPL.PKID AS UploadID ,
MONTH(UPL.ShopDate) AS [Month]
INTO #RelevantSummary
FROM tblPROMsExportSummary AS PES
INNER JOIN TVF_GetRelevantScorecards(@ProcedureID, @AreaID, @StartDate, @EndDate) AS RES ON RES.PROMSID = PES.PROMSID
INNER JOIN tblUploadedScorecards AS UPL ON PES.PROMSID = UPL.PEMSID
-- also get them for all PCTs, @AreaID hardcoded to 82
SELECT DISTINCT
PES.FKProcedureID ,
PES.PROMSID ,
UPL.PKID AS UploadID ,
MONTH(UPL.ShopDate) AS [Month]
INTO #RelevantSummaryPCT
FROM tblPROMsExportSummary AS PES
INNER JOIN TVF_GetRelevantScorecards(@ProcedureID, 82, @StartDate, @EndDate) AS RES ON RES.PROMSID = PES.PROMSID
INNER JOIN tblUploadedScorecards AS UPL ON PES.PROMSID = UPL.PEMSID
I'm not as good as to rewrite the sub queries, but based on what you wrote :
I'd like to rewrite the following select statement without the sub selects; while it works at the moment as it is it only works if there's data, when one of the sub selects doesn't return data I get an error
I wonder if COALESCE could do the trick for your problem.
Using derived tables is what I was after, in the example above it can be achieved like this:
SELECT * FROM (
SELECT DISTINCT
PES.FKProcedureID ,
PES.PROMSID ,
UPL.PKID AS UploadID ,
MONTH(UPL.ShopDate) AS [Month]
INTO #RelevantSummary
FROM tblPROMsExportSummary AS PES
INNER JOIN TVF_GetRelevantScorecards(@ProcedureID, @AreaID, @StartDate, @EndDate) AS RES ON RES.PROMSID = PES.PROMSID
INNER JOIN tblUploadedScorecards AS UPL ON PES.PROMSID = UPL.PEMSID ) AS T1
INNER JOIN (
SELECT DISTINCT
PES.FKProcedureID ,
PES.PROMSID ,
UPL.PKID AS UploadID ,
MONTH(UPL.ShopDate) AS [Month]
INTO #RelevantSummaryPCT
FROM tblPROMsExportSummary AS PES
INNER JOIN TVF_GetRelevantScorecards(@ProcedureID, 82, @StartDate, @EndDate) AS RES ON RES.PROMSID = PES.PROMSID
INNER JOIN tblUploadedScorecards AS UPL ON PES.PROMSID = UPL.PEMSID ) AS T2
ON T1.PROMSID = T2.PROMSID
To quote directly from the 4guys post
What we are doing is first getting the result set from our derived table (the SELECT statement in the FROM clause). Once we have that resultset, it is as though it was a table in itself. We then perform the SELECT on the derived table, returning our results! You can find another example of using derived tables here on 4GuysFromRolla.com in the article Obtaining Ranked Values from a Table page.
Though my final select looks more like this:
SELECT ISNULL(Volume, 0) AS Volume ,
ISNULL(PCTAverage, 0) AS PCTAverage ,
ShortMonth AS [Month] ,
DisplayOrder
FROM ( SELECT COUNT(DISTINCT ( PROMSID )) AS Volume ,
RS.YearMonth
FROM @RelevantSummary AS RS
GROUP BY YearMonth ) AS RS
INNER JOIN ( SELECT CAST(CAST(COUNT(PROMSID) AS DECIMAL(8, 3))
/ ( SELECT ISNULL(COUNT(DISTINCT RES.Branch), 1)
FROM tblPROMsExportSummary AS PES
INNER JOIN TVF_GetRelevantScorecards(@ProcedureID, @RootReportLevelID, @ReportLevelID, @StartDate,
@EndDate) AS RES ON RES.PROMSID = PES.PROMSID
INNER JOIN tblUploadedScorecards AS UPL ON PES.PROMSID = UPL.PEMSID
WHERE RES.YearMonth = PCT.YearMonth
GROUP BY RES.YearMonth ) AS DECIMAL(8, 3)) AS PCTAverage ,
YearMonth
FROM @RelevantSummaryPCT AS PCT
GROUP BY YearMonth ) AS PCT ON RS.YearMonth = PCT.YearMonth
RIGHT OUTER JOIN ( SELECT *
FROM dbo.TVF_Months(@StartDate, @EndDate) ) AS TVF ON TVF.DisplayOrder = RS.YearMonth
精彩评论