I am having a small challenge with a query I am trying to develop.
Here is what my table looks like:-
Accounts Table
ClientNo AccountType Balance
1234 SUP1 25
1234 SUP1.1 35
1234 RET1 20
1111 SUP1 50
1111 DIS4 60
I am trying to get to a result that looks like the following:-
ClientNo TotSupBal TotSuppAccts TotRetBal TotRetAccts TotDisBal TotDisAccts
1234 70 2 20 1 0 0
1111 50 1 0 0 60 1
Essentially a client can be in the Accounts table many times as there can be many accounts per client.
The accounts types will always start with the same characters to begin with however depending on how many of these accounts the number can be anything really and subsequent accounts will always be a deceminal then a number... Eg the first SUP account is simply SUP1, however the next SUP account will be SUP1.1, then SUP1.2 etc...
I have written the following query
SELECT ClientNo, SUM(Balance) AS TotSupBal, COUNT(AccountType) AS TotSuppAccts
FROM Account
WHERE (AccountType LIKE 'SUP1.%') OR (AccountType = 'SUP1')
GROUP BY ClientNo
* The reason there is 2 different WHERE clauses is because I can not just use SUP1% as there are accounts like SUP12 which are not the same as as a SUP1.
This Query works fine, however it only produces a listing for those of the account type of SUP. How can I produce the same sort of output, however across multiple columns for each account type?
I am using Microsoft SQL 2008 R2
PIVOT is what you need >> http://msdn.microsoft.com/en-us/library/ms177410(v=sql.105).aspx
Here is a fully working solution:
WITH Accounts (AccountCategory, ClientNo, Balance) as (
select
case
when AccountType like 'SUP%' then 'sup'
when AccountType like 'RET%' then 'ret'
when AccountType like 'DIS%' then 'dis'
end as AccountCategory,
ClientNo,
Balance
from Account
)
select * from (
select ClientNo, sup as TotSupBal, ret as TotRetBal, dis as TotDisBal from Accounts as SourceTable PIVOT (
SUM(Balance)
FOR AccountCategory IN ([sup], [ret], [dis])
) as pt
) as sums inner join (
select ClientNo, sup as TotSupAccts, ret as TotRetAccts, dis as TotDisAccts from Accounts as SourceTable PIVOT (
COUNT(Balance)
FOR AccountCategory IN ([sup], [ret], [dis])
) as pt
) as counts on sums.ClientNo = counts.ClientNo
Try it on SqlFiddle: http://sqlfiddle.com/#!6/d5e91/26
Let me assume that you know what the account types are in advance. In this case, you just want a conditional aggregation sum:
select clientNo,
sum(case when (AccountType LIKE 'SUP1.%') OR (AccountType = 'SUP1')
then Balance
end) as TotSupBal,
sum(case when (AccountType LIKE 'SUP1.%') OR (AccountType = 'SUP1')
then 1
else 0
end) as TotSupAccts,
sum(case when left(AccountType, 3) = 'RET'
then Balance
end) as TotRetBal,
sum(case when left(AccountType, 3) = 'RET'
then 1
else 0
end) as TotRetAccts,
. . .
from account
group by clientNo
I'm not sure what the exact logic is for the other accounts, so I'm just looking at the first three characters.
SELECT
ClientNo,
SUM(Balance) AS TotSupBal,
COUNT(AccountType) AS TotSuppAccts,
ret_bal AS TotRetBal,
total_ret AS TotRetAccts
FROM
Account,
(
SELECT
ClientNo c_num,
SUM(Balance) AS ret_bal,
COUNT(AccountType) total_ret
WHERE AccountType LIKE 'RET%'
GROUP BY ClientNo
) Table1RET_type -- Your name for new table(You create new temporary table for you select)
WHERE
((AccountType LIKE 'SUP1.%') OR (AccountType = 'SUP1'))
AND Table1RET_type.c_num = ClientNo -- This is called join Table(google it for more info)
GROUP BY ClientNo
Now you have to repeat this logic for all Columns you want to create.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.