find last balance as on a particular date - sql-server-2008

I have a table of deposit/withdrawal transactions. I want to find the balance of each account as on a given date.
acctno date trantype amount balance seqno
12 1/2/14 dep 100 100 1
12 3/2/14 wdl 50 50 2
12 1/3/14 dep 200 250 3
13 2/2/14 dep 500 500 1
13 5/2/14 dep 100 600 2
13 5/4/14 dep 100 700 2
14 1/3/14 dep 200 200 1
Now I want to find the balance of each account as on 1/4/2014 and the reult should be something like this
acctno balance
12 250
13 600
14 200

Try this:
SELECT T1.Acctno, T1.Balance
FROM YourTable T1 INNER JOIN
(
SELECT T2.Acctno, T2.Date, MAX(T2.seqno) As MaxSeqno
FROM YourTable T2
GROUP BY T1.Acctno, T2.Date
)
ON(T1.Acctno = T2.Acctno AND T1.Date = T2.Date AND T1.seqno = MaxSeqno)
WHERE T1.Date = '2014-04-01'

try
select * from (select *,row_number() over
(partition by acctno order by date desc) as rno
from yourtable t WHERE T.Date <= '2014-04-01') t1 where rno=1

Related

Combine columns from 2 queries

I have 2 queries where I group by week, by quarter and year using added_on, the problem comes in when I try to combine the queries since the first query weeks are from 1,2,3,4,5,....,25, it has transactions in every week of the year and the second query is 1,4,5,8,15,25 because it does not have transactions on some weeks and I need for both to have 1,2,3,4,5,6,7,...,25 is there any way to achieve this?
transaction table
id
value
added_on
currency_id
1
100
2020/01/20
2
320
2020/2/10
currency table
id
type
1
USD
2
EUR
My query is looking like this
SELECT
week_usd,
week_eur,
total_usd,
total_eur,
quarter_year
FROM
(SELECT
WEEK(transaction.added_on) AS week_usd,
SUM(transaction.value) AS total_usd,
CONCAT(QUARTER(transaction.added_on)," ", YEAR(transaction.added_on)) AS quarter_year
FROM transaction
JOIN currency ON transaction.currency_id = currency.id
WHERE
currency.type = 'USD'
GROUP BY 1,3
) AS table1,
(SELECT
WEEK(transaction.added_on) AS week_eur,
SUM(transaction.value) AS total_eur,
CONCAT(QUARTER(transaction.added_on)," ", YEAR(transaction.added_on)) AS quarter_year
FROM transaction
JOIN currency ON transaction.currency_id = currency.id
WHERE
currency.type = 'EUR'
GROUP BY 1,3
) AS table2
The problem with my query is that it will display like this
week_usd
week_eur
total_usd
total_eur
quarter_year
0
1
100
150
1 2020
1
1
100
150
1 2020
2
1
100
150
1 2020
3
1
100
150
1 2020
4
1
100
150
1 2020
5
1
100
150
1 2020
6
1
100
150
1 2020
7
1
100
150
1 2020
8
1
100
150
1 2020
You need first to create unique list of dates before getting joins of totals:
Select date_list.quarter_year
, date_list.week
, USD.total_usd
, EUR.total_eur
from
( select distinct CONCAT(QUARTER(transaction.added_on)," ", YEAR(transaction.added_on)) AS quarter_year
, WEEK(transaction.added_on) week
from transaction
) as date_list
Left Join (
select CONCAT(QUARTER(transaction.added_on)," ", YEAR(transaction.added_on)) AS quarter_year
, WEEK(transaction.added_on) week
, SUM(transaction.value) AS total_usd
from transaction
join currency on transaction.currency_id = currency.id
where currency.type = 'USD'
group by 1,2
) as USD on date_list.quarter_year = USD.quarter_year and date_list.week = USD.week
Left Join (
select CONCAT(QUARTER(transaction.added_on)," ", YEAR(transaction.added_on)) AS quarter_year
, WEEK(transaction.added_on) week
, SUM(transaction.value) AS total_eur
from transaction
join currency on transaction.currency_id = currency.id
where currency.type = 'EUR'
group by 1,2
) as EUR on date_list.quarter_year = EUR.quarter_year and date_list.week = EUR.week ;

In a purchase data table,how to query day by day performance using SQL

I have the following table and I just want to figure out the revenue difference by day. Like day 1 revenue and day 2=day 1- day2 so on
Date CustomerID Quantity Price Revenue
2020-1-1 C1 4 10 40
2020-1-2 C2 7 20 140
2020-1-3 C3 8 50 400
2020-1-4 C4 5 90 450
2020-1-5 C5 8 60 480
2020-1-6 C6 9 100 900
The expected result is
Date Revenue_Difference
2020-1-1 40
2020-1-2 100 i.e. 140-40
2020-1-3 260 i.e. 400-140
2020-1-4 50 i.e. 450-400
If you are using MySQL 8+, then you may use LAG here:
SELECT
Date,
Revenue - LAG(Revenue, 1, 0) OVER (ORDER BY Date) AS Revenue_Difference
FROM yourTable
ORDER BY Date;
On earlier versions of MySQL, you may use a correlated subquery in place of LAG:
SELECT
Date,
Revenue - (SELECT t2.Revenue FROM yourTable t2
WHERE t2.Date < t1.Date
ORDER BY t2.Date DESC LIMIT 1) AS Revenue_Difference
FROM yourTable t1
ORDER BY Date;

Conditional SQL Query on Multiple Rows

I am trying to find out which customers have defaulted on their loans. I would like to query the dataset to find the User_id of customers who have not paid in the last 60 days, but and not sure how to implement this in SQL.
User_id Due_Date Loan_Amount Paid_Amount
1 2012-04-04 16:14:12 500 40
1 2012-05-04 16:14:12 500 40
1 2012-06-04 16:14:12 500 0
1 2012-07-04 16:14:12 500 0
1 2012-08-04 16:14:12 500 0
2 2012-02-15 03:30:55 2030 100
2 2012-03-15 03:30:55 2030 100
2 2012-04-15 03:30:55 2030 100
3 2012-01-03 12:24:42 777 10
3 2012-02-03 12:24:42 777 0
3 2012-03-03 12:24:42 777 0
3 2012-04-03 12:24:42 777 0
In pseudocode (shown in bold) would look something like this, but I can't seem to implement it in MySQL:
SELECT User_id from TABLE_NAME WHERE Loan_Amount > 0 AND [the value Paid_Amount has been null for over 60 days]
Desired Output:
Users 1 and 3 in the above query would be returned because they have not paid for three consecutive periods.
NOTE: Due_Date is a time stamp
Any ideas would be very much appreciated!
Looks like you can use the DATEDIFF(date1, date1) function to obtain a list of delinquent borrowers.
SELECT DISTINCT
user_id
FROM table_name n
JOIN (SELECT user_id, max(due_date) maxDate FROM table_name GROUP BY user_id) t
ON n.user_id = t.user_id
AND n.due_date = t.maxDate
WHERE
loan_amount > 0
AND paid_amount IS NULL
AMD DATEDIFF(due_date, getdate()) > 60
My previous query was wrong, try this
select distinct t1.User_id
from TABLE_NAME t1
inner join (
select ts1.User_id, sum(ts1.Paid_Amount) as Paid_Amount_Total
from TABLE_NAME ts1
group by ts1.User_id
) t2
on t1.User_id=t2.User_id and t1.Loan_Amount>t2.Paid_Amount_Total
)
where
t1.Loan_Amount > 0
and t1.User_id not in (
select ts2.User_id
from TABLE_NAME ts2
where ts2.Due_Date>=DATE_SUB(NOW(), INTERVAL 60 DAY) and ts2.Paid_Amount>0
)
t1, ts1, ts2 - are aliases for TABLE_NAME

MySql Sum with two tables

I have two tables
t1
id Name Total
1 Alex 100
2 Bob 100
1 Alex 100
t2
id Amount
1 2
1 3
1 4
2 12
2 13
I need to get sum of Total and Amount.
**select Name, sum(Total) as Total, sum(Amount) as Amount,day
from t1,t2
Where t1.id=t2.id
group by Name**
Result:
Alex 600 18
Bob 200 25
Incorrect sum of Amount!
**select Name, sum(distinct Total) as Total, sum(Amount) as Amount,day
from t1,t2
Where t1.id=t2.id
group by Name**
Result:
Alex100 18
Bob 100 25
Incorrect sum of Amount.
MySql use distinct by value, i need distinct by id
corect result that need be is
Alex 200 18
Bob 100 25
How to get to this result?
select t1.Name,
sum(t1.Total) as Total,
sum(t2.Amount) as Amount,
day
from t1
left join
(
select id, sum(Amount) as Amount
from t2
group by id
) t2 on t1.id = t2.id
group by t1.Name

select price having max year in another column

I have following select result
Code Price Year
1 200 2013
1 100 2012
2 250 2011
2 275 2012
2 300 2010
But I want following something like this with one extra column which hold price based on maximum year,
Code Price Year ExPrice
1 200 2013 200
1 100 2012 200
2 250 2011 275
2 275 2012 275
2 300 2010 275
Sorry for bad English and wrong way for asking this question.
You can do it with cross apply and select top 1 ... order by:
select Code, Price, Year, ExPrice
from TableName T
cross apply (
select top 1 Price
from TableName
where Code = T.Code
order by Year desc
) p(ExPrice)
or row_number and join (whatever you prefer):
;with cte as (
select Code, Price as ExPrice, rn = row_number() over (partition by Code order by Year desc)
from TableName
)
select T.Code, Price, Year, ExPrice
from TableName T
join cte on cte.Code = T.Code and cte.rn = 1
SQLFiddle sample
Try something like this:
SELECT T1.Code, T1.Price, T1.Year, T2.Price
FROM Table T1
INNER JOIN Table T2 ON T1.Code = T2.Code AND
T2.Year = (SELECT MAX(Year) FROM Table WHERE Table.Code = T2.Code)