bcarrolluk
asked on
SQL 2000: Nested Case/Where Statement for summing withing date ranges
I have a table containing financial transactions (stran). I need to create an 'age of debtors' summary query which groups on the customer reference (st_account) and gives the total sum of transaction balances (sum(st_trbal) and then balances within date (st_trdate) range dependant values within 30 days and older than 30, 60, 90 days ie. (sum(st_trbal)) where st_trdate > GETDATE()-30 As AmtCurrent, (sum(st_trbal)) where st_trdate Between GETDATE()-60 And GETDATE()-30 As Amt30, Between GETDATE()-90 And GETDATE()-60 As Amt60, < GETDATE()-90 As Amt90.
I have come up with the following, but the syntax seems all wrong and SQL Server 2000 query builder does not like case so I am writing direct in Query Analyser:
SELECT st_account AS CustomerRef, SUM(st_trbal) AS TotalBalance, sum(st_trbal) where st_trdate > GETDATE()-30 As AmtCurrent, sum(st_trbal) where st_trdate Between GETDATE()-60 And GETDATE()-30 As Amt30, sum(st_trbal) Where st_trdate Between GETDATE()-90 And GETDATE()-60 As Amt60, sum(st_trbal) Where st_trdate < GETDATE()-90 As Amt90
FROM dbo.STRAN
GROUP BY st_account
I realise I could build and link views of the Current, 30, 60 and 90 day balance but I'm sure it should be possible to do this as one query on one table using Case or something - I may need to include data from more tables later but this is the basis of the report/query.
Please Help
Bryan
I have come up with the following, but the syntax seems all wrong and SQL Server 2000 query builder does not like case so I am writing direct in Query Analyser:
SELECT st_account AS CustomerRef, SUM(st_trbal) AS TotalBalance, sum(st_trbal) where st_trdate > GETDATE()-30 As AmtCurrent, sum(st_trbal) where st_trdate Between GETDATE()-60 And GETDATE()-30 As Amt30, sum(st_trbal) Where st_trdate Between GETDATE()-90 And GETDATE()-60 As Amt60, sum(st_trbal) Where st_trdate < GETDATE()-90 As Amt90
FROM dbo.STRAN
GROUP BY st_account
I realise I could build and link views of the Current, 30, 60 and 90 day balance but I'm sure it should be possible to do this as one query on one table using Case or something - I may need to include data from more tables later but this is the basis of the report/query.
Please Help
Bryan
Hi bcarrolluk,
Try this
-- code start
SELECT st_account AS CustomerRef,
sum(case when st_trdate > GETDATE()-30 then st_trbal else o end) As AmtCurrent
sum(case when st_trdate Between GETDATE()-60 And GETDATE()-30 then st_trbal else o end) As Amt30
sum(case when st_trdate Between GETDATE()-90 And GETDATE()-60 then st_trbal else o end) As Amt60
sum(case when st_trdate < GETDATE()-90 then st_trbal else o end) As Amt90
FROM dbo.STRAN
GROUP BY st_account
-- code end
HTH
R.
Try this
-- code start
SELECT st_account AS CustomerRef,
sum(case when st_trdate > GETDATE()-30 then st_trbal else o end) As AmtCurrent
sum(case when st_trdate Between GETDATE()-60 And GETDATE()-30 then st_trbal else o end) As Amt30
sum(case when st_trdate Between GETDATE()-90 And GETDATE()-60 then st_trbal else o end) As Amt60
sum(case when st_trdate < GETDATE()-90 then st_trbal else o end) As Amt90
FROM dbo.STRAN
GROUP BY st_account
-- code end
HTH
R.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
jus c whether this will help u
select CustomerRef,sum([30]) as [30],sum([30-60]) as [30-60],sum([60-90]) as [60-90] from
(select st_account AS CustomerRef,case when datediff(d,st_trdate ,getdate())<30 then st_trbal else 0 end as '30',
case when datediff(d,st_trdate ,getdate())>=30 and datediff(d,st_trdate ,getdate())<60 then st_trbal else 0 end as '30-60',
case when datediff(d,st_trdate ,getdate())>=60 and datediff(d,st_trdate ,getdate())<90 then st_trbal else 0 end as '60-90'
from dbo.STRAN
)
dt
group by CustomerRef order by CustomerRef
select CustomerRef,sum([30]) as [30],sum([30-60]) as [30-60],sum([60-90]) as [60-90] from
(select st_account AS CustomerRef,case when datediff(d,st_trdate ,getdate())<30 then st_trbal else 0 end as '30',
case when datediff(d,st_trdate ,getdate())>=30 and datediff(d,st_trdate ,getdate())<60 then st_trbal else 0 end as '30-60',
case when datediff(d,st_trdate ,getdate())>=60 and datediff(d,st_trdate ,getdate())<90 then st_trbal else 0 end as '60-90'
from dbo.STRAN
)
dt
group by CustomerRef order by CustomerRef
ASKER
Cheers Regbes, that's spot on.
first off, the order in sql statements:
http://msdn.microsoft.com/library/en-us/tsqlref/ts_sa-ses_9sfo.asp?frame=true
second,
this grouping is not as straightforward as you might think.
you need to create seperate columns for each agegroup,
and the easiest way to achieve that is probably a self-join for each group.
you can then sum over those groups.