Calculating Closing and Opening Balance in SQL - sql

I have a table 'transactions(txDate, amount, txType) where txType can "credit" or "debit".
I need to get an opening and closing balance when returning transactions between two dates.
The first row of the results should be the Opening Balance, then a list of all tx between the dates and the last row to be a Closing balance
Getting the list isn't a train smash but for the balances, I currently have the following
SELECT SUM(amount) AS [Opening Balance]
FROM
(
SELECT SUM([Amount]) amount
FROM [dbo].[Transaction]
WHERE [txDate] <= #startDate
AND [txType] = 'credit'
UNION ALL
SELECT 0 - SUM([Amount]) amount
FROM [dbo].[Transaction]
WHERE [TransactionDate] <= #startDate
AND [txType] = 'debit'
) Transactions
this gives a very big amount than what it should be.
And for the Closing balance, I have no idea how to go about it

You could use CASE in SUM
select sum(case when txType = 'credit' and transactionDate <= #startDate
then amount end) -
sum(case when txType = 'debit' and transactionDate <= #startDate
then amount end)[Opening Balance],
sum(case when txType = 'credit' and transactionDate <= #endDate
then amount end) -
sum(case when txType = 'debit' and transactionDate <= #endDate
then amount end)[Closing Balance]
from transaction

Related

SQL: Create Multiple Selects Based One Date

I've been searching for help on this but I can't seem to find the solution. What I have is:
Table called Details_Orders.
Columns: CustomerName, InvoiceDate, SaleAmount and SaleCost.
What I want to do is select a date ('1-1-2015') and display the Customer Name, the Date ('1-1-2015'), the sum of SaleAmount for that Date, and the Sum of the SaleCost. And here's the part I'm having problems with, I want the next columns to display the previous months SaleAmount and SaleCost, then the previous YEARS SaleAmount and SaleCost.
I'm having trouble figuring out how to code the Previous Time Periods Select statements. Any help on this would be greatly appreciated.
Select
CustomerName,
InvoiceDate,
Sum(SaleAmount),
Sum(SaleCost),
*PREVIOUS MONTH Sum(SalesAmount) DATEADD(MONTH,-1,'1-1'2015'),
PREVIOUS MONTH Sum(SalesCost) DATEADD(MONTH,-1,'1-1'2015'),
PREVIOUS YEAR Sum(SalesAmount) DATEADD(YEAR,-1,'1-1'2015'),
PREVIOUS YEAR Sum(SalesCost) DATEADD(YEAR,-1,'1-1'2015')*
From Details_Orders
WHERE InvoiceDate='1-1-2015'
Basic
You want to use conditional aggregation, and also need a group by. It is a bit unclear what the exact definitions of previous month and year are. Here is one interpretation:
Select CustomerName,
Sum(case when InvoiceDate = thedate then SaleAmount else 0 end),
Sum(case when InvoiceDate = thedate then SaleCost else 0 end),
Sum(case when year(InvoiceDate)*12 + month(InvoiceDate) =
year(thedate)*12 + month(thedate) - 1
then SaleAmount else 0
end),
Sum(case when year(InvoiceDate)*12 + month(InvoiceDate) =
year(thedate)*12 + month(thedate) - 1
then SaleCost else 0
end),
Sum(case when InvoiceDate < thedate and
InvoiceDate >= dateadd(year, -1, thedate
then SaleAmount else 0
end),
Sum(case when InvoiceDate < thedate and
InvoiceDate >= dateadd(year, -1, thedate
then SaleCost else 0
end)
From (select cast('2015-01-01' as date) as thedate
) params cross join
Details_Orders o
group by CustomerName;

How to get records according to column data

I have a table in sql whose name is Trans which contain 4 columns
CustomerID int
TransDate datetime
TransType char(1)
Amount float
CustomerID can contain duplicate ID's but record contain different TransDate or TransType or Amount. TransType contain 'c' for credit and 'd' for debit.
I want to select CustomerId, year, CreditAmount and DebitAmount where CreditAmount is amount where TransType is 'c' and DebitAmount is amount where TransType is 'd'. Year is calculated from TransDate which contain date and time.
I think this is what you are looking for:
select customerid,
datepart(yyyy, transdate) as yr,
sum(case when transtype = 'c' then amount else 0 end) as creditamount,
sum(case when transtype = 'd' then amount else 0 end) as debitamount
from trans
group by customerid,
datepart(yyyy, transdate)
This does assume you want the total credits, for each year, and total debits, for each year, for each customer.
I want to select CustomerId, year, CreditAmount and DebitAmount where
CreditAmount is amount where TransType is 'c' and DreditAmount is
amount where TransType is 'd'. Year is calculated from TransDate which
contain date and time.
I am not sure that I understand you correctly, but you can check:
SELECT
CustomerId
,[Year] = YEAR(TransDate)
,[CreditAmount] = Amount
,[DebitAmount] = (SELECT Amount
FROM Trans t1
WHERE t1.CustomerId = t.CustomerId
AND t1.TransDate = t.TransDate
AND t1.TransType = 'd')
FROM Trans t
WHERE t.TransType = 'c';
I assumed that CustomerId/TranDate/TransType are unique.

SQL: Group SUM values by date ranges and show in multiple columns by date

I have a SQL table showing charge amounts per person and an associated date. I'm looking to create a printout of each person's charges per month. I have the following code which will show me everyone's data for ONE month but I'd like to put this in one report without having to rerun this for every month's date range. Is there a way to pull this data all at once? Essentially I'd like the columns to show:
Last Name January February March Etc
name amt amt amt
Here is my code to pull this data for April as an example. You'll see the dates are codes as YYYYMMDD. This code works perfectly for one month at a time.
select pm.last_name, SUM(amt) as Total_Charge from charges c
inner join provider_mstr pm ON c.rendering_id = pm.provider_id
where begin_date_of_service >= '20150401' and begin_date_of_service <= '20150431'
group by pm.last_name
A generic solution uses SUM over CASEs:
select pm.last_name,
SUM(case when begin_date_of_service >= '20150101' and begin_date_of_service < '20150201' then amt else 0 end) as Total_Charge_Jan,
SUM(case when begin_date_of_service >= '20150201' and begin_date_of_service < '20150301' then amt else 0 end) as Total_Charge_Feb,
SUM(case when begin_date_of_service >= '20150301' and begin_date_of_service < '20150401' then amt else 0 end) as Total_Charge_Mar,
...
from charges c
inner join provider_mstr pm ON c.rendering_id = pm.provider_id
where begin_date_of_service >= '20150101' and begin_date_of_service < '20160101'
group by pm.last_name
Depending on your DBMS you might have a PIVOT function or similar...
Change SUM(amt) as Total_Charge to the following for each period
SUM(CASE WHEN begin_date_of_service BETWEEN '20150401' AND '20150430' THEN amt ELSE 0 END) AS April_Amt
SUM(CASE WHEN begin_date_of_service BETWEEN '20150301' AND '20150331' THEN amt ELSE 0 END) AS March_Amt
And update WHERE clause to include all date ranges for pull.
A condition will evaluate to 1 or 0 in a product, so you could use the following approach to do a selective sum:
select
pm.last_name,
SUM(amt * (begin_date_of_service >= '20150401' and begin_date_of_service <= '20150431')) AS 'april',
SUM(amt * (begin_date_of_service >= '20150501' and begin_date_of_service <= '20150530')) AS 'may'
...
from charges c
inner join provider_mstr pm ON c.rendering_id = pm.provider_id
group by pm.last_name

SQL Query: Including Two Sums based on different criteria from the same table

I currently have the following sql query
SELECT [Date], DATENAME(dw,[Date]) AS Day, SUM(Units) AS TotalUnits
FROM tblTimesheetEntries
WHERE UserID = 'PJW'
AND Date >= '2013-01-01'
GROUP BY [Date]
ORDER BY [Date] DESC;
Which returns the Total [Units] for a given user and date.
However I would like to produce two separate Total Units based on a new criteria i.e. whether or not the [Units] where 'Chargeable or Not'. There is a field in tblTimeSheets called Chargeable which is a boolean (true for chargeable, false for not). How do I incorporate this to show two Sums one for each type of Units?
You can use a CASE with the SUM() to calculate the separate totals:
SELECT [Date],
DATENAME(dw,[Date]) AS Day,
sum(case when Chargeable = 1 then Units else 0 end) ChargeableTotal,
sum(case when Chargeable = 0 then Units else 0 end) NotChargeableTotal,
sum(Units) AS TotalUnits
FROM tblTimesheetEntries
WHERE UserID = 'PJW'
AND Date >= '2013-01-01'
GROUP BY [Date]
ORDER BY [Date] DESC;

SQL Query Sum up Values Actual Year to Date and What the Average YTD

I need a query that, totals up expenses Actual YTD, Average YTD( out of all the years , what is my average year), Last Year YTD
I need 3 pieces of Data: Actual YTD | Average YTD | Last Years|
This is what I have so far:
select SUM(Expenses)
,DATEADD(year, datediff(year,0,[Date]), 0)
from table1
group by
DATEADD(year, datediff(year,0,[Date]), 0)
)
Try this:
DECLARE #currentYear int
SELECT #currentYear = DATEPART(year, GETDATE())
SELECT SUM(CASE WHEN DATEPART(year,[date]) = #currentYear
THEN Expenses ELSE 0 END) AS 'Actual YTD',
SUM(Expenses) / COUNT( DISTINCT DATEPART(year,[date])) AS 'Average YTD',
SUM(CASE WHEN DATEPART(year,[date]) = #currentYear -1
THEN Expenses ELSE 0 END) AS 'Last Year YTD'
FROM Table1
SQL Fiddle
Try this
select
AVG(case when
[date]>=DATEADD(year, datediff(year,0,getDate())-1, 0) and
[date]<DATEADD(year, datediff(year,0,getDate()), 0)
then Expenses end)
as average_ytd,
sum(case when
[date]>=DATEADD(year, datediff(year,0,getDate())-1, 0) and
[date]<DATEADD(year, datediff(year,0,getDate()), 0)
then Expenses else 0 end)
as actual_ytd,
sum(case when
[date]>=DATEADD(year, datediff(year,0,getDate())-2, 0) and
[date]<DATEADD(year, datediff(year,0,getDate())-1, 0)
then Expenses else 0 end)
as lat_year_ytd
from
table1