Use a combination of a Common Table Expression (CTE), BETWEEN and CASE ...
;with cte as
(
SELECT CAST((INT_ARREARS+PRIN_ARREARS)/DEDUCT AS INT) as COMP_ARREARS ,
SUM((INT_ARREARS+PRIN_ARREARS)) AS SUM_INT_PRIN
FROM HLOANS where DEDUCT >0 and INT_ARREARS+PRIN_ARREARS>0
AND CAST((INT_ARREARS+PRIN_ARREARS)/DEDUCT AS INT) >0
AND CMONTH=@ZMONTH AND CYEAR=@ZYEAR
GROUP BY CAST((INT_ARREARS+PRIN_ARREARS)/DEDUCT AS INT)
)
SELECT CASE WHEN COMP_ARREARS BETWEEN 1 AND 3 THEN CAST('1-3' AS Varchar(8))
WHEN COMP_ARREARS BETWEEN 4 AND 6 THEN '4-6'
WHEN COMP_ARREARS BETWEEN 7 AND 9 THEN '7-9'
ELSE 'The Rest' END AS [Grouping],
SUM(SUM_INT_PRIN) AS SumOfGroup
FROM cte
GROUP BY CASE WHEN COMP_ARREARS BETWEEN 1 AND 3 THEN CAST('1-3' AS Varchar(8))
WHEN COMP_ARREARS BETWEEN 4 AND 6 THEN '4-6'
WHEN COMP_ARREARS BETWEEN 7 AND 9 THEN '7-9'
ELSE 'The Rest' END
ORDER BY 1
Things to note:
- The body of the CTE (
cte
) is
your original query (minus the ORDER BY which is not allowed)
- The first column in the SELECT from the CTE uses CASE and BETWEEN to get the "title" of the groupings we need.
- The GROUP BY clause effectively repeats that grouping title
- I couldn't be bothered to repeat it all again for the ORDER BY clause so I used the trick of saying "order by the first column" ...
ORDER BY 1
- It would be great if I could have just said
GROUP BY 1
as well but that generates an error :(
Quote:
Each GROUP BY expression must contain at least one column that is not an outer reference.
- I didn't have to use a CTE ... I could have written something like
SELECT CASE WHEN CAST((INT_ARREARS+PRIN_ARREARS)/DEDUCT AS INT) BETWEEN 1 AND 3 THEN CAST('1-3' AS Varchar(8))
WHEN CAST((INT_ARREARS+PRIN_ARREARS)/DEDUCT AS INT) BETWEEN 4 AND 6 THEN '4-6'
WHEN CAST((INT_ARREARS+PRIN_ARREARS)/DEDUCT AS INT) BETWEEN 7 AND 9 THEN '7-9'
ELSE 'The Rest' END AS [Grouping],
SUM((INT_ARREARS+PRIN_ARREARS)) AS SumOfGroup
FROM HLOANS where DEDUCT >0 and INT_ARREARS+PRIN_ARREARS>0
AND CAST((INT_ARREARS+PRIN_ARREARS)/DEDUCT AS INT) >0
AND CMONTH=@ZMONTH AND CYEAR=@ZYEAR
GROUP BY CASE WHEN CAST((INT_ARREARS+PRIN_ARREARS)/DEDUCT AS INT) BETWEEN 1 AND 3 THEN CAST('1-3' AS Varchar(8))
WHEN CAST((INT_ARREARS+PRIN_ARREARS)/DEDUCT AS INT) BETWEEN 4 AND 6 THEN '4-6'
WHEN CAST((INT_ARREARS+PRIN_ARREARS)/DEDUCT AS INT) BETWEEN 7 AND 9 THEN '7-9'
ELSE 'The Rest' END
ORDER BY 1
But apart from the fact it is more difficult to read, look at the number of times it is having to recalculate the field that eventually becomes
COMP_ARREARS
!