Click here to Skip to main content
15,919,500 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
SQL
DECLARE @LOAN_BALANCE DECIMAL,
	        @ZMONTH INT,
	        @ZYEAR  INT,
	        @OLEM   DECIMAL
	        
	  SET @ZMONTH=5
	  SET @ZYEAR =2015       
	
 	
;with cte as
	(
		SELECT  CAST((INT_ARREARS+PRIN_ARREARS)/DEDUCT AS INT) as COMPS ,
		        INT_ARREARS+PRIN_ARREARS AS TOTS,
		        IDNO,AC_BALANCE,LOANUMBER,CUSTOMER
		 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
	)
SELECT	 	CUSTOMER                 AS 'CUSTOMER' , 
			AC_BALANCE               AS 'LOAN BALANCE',
		  CASE WHEN COMPS BETWEEN 1 AND 3 THEN CAST('1-3' AS Varchar(8))
			   WHEN COMPS BETWEEN 4 AND 6 THEN '4-6'
			ELSE 'The Rest' END AS [Grouping],
		    TOTS AS 'TOTS'                     ,
		    00.00   AS 'OLEM'                  ,  
		    00.00   AS 'SUB-STANDARD'          ,
		    00.00   AS 'LOSS'    
			
FROM cte
ORDER BY CASE WHEN COMPS BETWEEN 1 AND 3 THEN CAST('1-3' AS Varchar(8))
			WHEN COMPS BETWEEN 4 AND 6 THEN '4-6'
			WHEN COMPS BETWEEN 7 AND 12 THEN '7-12'
			ELSE 'The Rest' END


-------------------------------------------------------------------------------------
outcome
-------------------------------------------------------------------------------------

CUSTOMER        LOAN BALANCE    Grouping        TOTS    OLEM     SUB-STANDARD
----------------------------------------------------------------------------
CALTECH         7676710.46      1-3         171631.26   0.00          0.00
DANNEX          3058630.15      4-6          49452.68   0.00          0.00
PLOT            4150208.33      1-3         470323.78   0.00          0.00


request
-------

Expected Outcome


CUSTOMER     LOAN BALANCE    Grouping       TOTS        OLEM     SUB-STANDARD
----------------------------------------------------------------------------
CALTECH         7676710.46      1-3         171631.26   171631.26       0.00
DANNEX          3058630.15      4-6          49452.68   0.00        49452.68
PLOT            4150208.33      1-3         470323.78   470323.78       0.00



Group '1-3' goes with 'OLEM'

GROUP '4-6' goes with 'SUB-STANDARD'



Please adjust the Select Statement above so as to achieve the Expected

What I have tried:

Checked the internet and reviewed some sql statements, all to no avail.
Posted
Updated 24-Apr-16 4:18am
v7
Comments
CHill60 23-Apr-16 11:51am    
What are OLEM and SUB-STANDARD meant to be - you have hard-coded the value 0.00 to them

1 solution

My first thought with this was to introduce a second CTE to assign the groupings to the rows and therefore make it easier to use a GROUP BY. E.g.
SQL
DECLARE @ZMONTH INT = 5
DECLARE @ZYEAR  INT = 2015

;with cte as
(
		SELECT  CAST((INT_ARREARS+PRIN_ARREARS)/DEDUCT AS INT) as COMPS ,
		        INT_ARREARS+PRIN_ARREARS AS TOTS,
		        IDNO,AC_BALANCE,LOANNUMBER,CUSTOMER
		 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

), cte2 as   -- This CTE is just to get the grouping in place
(
	SELECT	 	CUSTOMER, AC_BALANCE,
		  CASE WHEN COMPS BETWEEN 1 AND 3 THEN CAST('1-3' AS Varchar(8))
			   WHEN COMPS BETWEEN 4 AND 6 THEN '4-6'
			ELSE 'The Rest' END AS [Grouping],
		    TOTS
	FROM cte
)
-- This query is to get the actual data required
SELECT CUSTOMER, SUM(AC_BALANCE) as [LOAN BALANCE], [Grouping], 
SUM(TOTS) AS TOTS, 
OLEM = CASE WHEN [Grouping] = '1-3' THEN SUM(TOTS) ELSE 0.0 END,
[SUB-STANDARD] = CASE WHEN [Grouping] = '4-6'  THEN SUM(TOTS) ELSE 0.0 END
FROM cte2
GROUP BY CUSTOMER, [Grouping]
ORDER BY [Grouping]

An alternative approach would be to have the groupings in a separate table which can then be part of a simple JOIN. I've used a TABLE variable here but it could just as easily be a temporary table or even a permanent table on the database.
SQL
DECLARE @ZMONTH INT = 5
DECLARE @ZYEAR  INT = 2015

DECLARE @Groupings TABLE (comp int, title varchar(30))
DECLARE @maxComp int = (select CAST(MAX((INT_ARREARS+PRIN_ARREARS)/DEDUCT) AS INT) FROM HLOANS)
;WITH q AS
(
    SELECT  1 AS num
    UNION ALL
    SELECT  num + 1
    FROM    q
    WHERE num < @maxComp
)
INSERT INTO @Groupings
SELECT  num, CASE WHEN num BETWEEN 1 AND 3 THEN CAST('1-3' AS Varchar(8))
			   WHEN num BETWEEN 4 AND 6 THEN '4-6'
			ELSE 'The Rest' END AS [Grouping]
FROM  q

;with cte as
(
		SELECT  CAST((INT_ARREARS+PRIN_ARREARS)/DEDUCT AS INT) as COMPS ,
		        INT_ARREARS+PRIN_ARREARS AS TOTS,
		        IDNO,AC_BALANCE,LOANNUMBER,CUSTOMER
		 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

)
SELECT CUSTOMER, SUM(AC_BALANCE) as [LOAN BALANCE], g.title AS [Grouping], 
SUM(TOTS) AS TOTS, 
OLEM = CASE WHEN G.[title] = '1-3' THEN SUM(TOTS) ELSE 0.0 END,
[SUB-STANDARD] = CASE WHEN G.title= '4-6'  THEN SUM(TOTS) ELSE 0.0 END
FROM cte
INNER JOIN @Groupings G ON cte.COMPS = g.comp
GROUP BY CUSTOMER, G.title
ORDER BY G.title


The first bit (q) is a recursive CTE that just generates the numbers 1 through to the maximum possible value of COMP and gives each of those numbers the title of the grouping that it falls into. My test data produced
num     title
1	1-3
2	1-3
3	1-3
4	4-6
5	4-6

The rest of the query is more or less the same as your original query but with a straight-forward JOIN to that list of numbers. It's then very easy to GROUP by the title from the temporary table rather than having CASE statements in the GROUP BY and ORDER BY clauses.

This should run a little faster than the alternative as all of the character handling has been taken out of the main query and is only "calculated" once per possible value.
 
Share this answer
 
Comments
Member 10744248 24-Apr-16 17:26pm    
Thank you very much

You are great

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900