I have a table in #SQL server 2008 that has transaction data. The table looks like this. I would like to have this in a sql statement.
TransactionId|TransactionDate|TransactionType|Amount|Balance|UserId
The transaction type can be one of four types, Deposit, Withdrawals, Profit and Stake. I give an example how it can look like in the transaction table. The balance is the Sum of amount column.
TransactionId|TransactionDate|TransactionType|Amount|Balance|UserId
1| 2013-03-25| Deposit| 150| 150| 1
2| 2013-03-27| Stake| -20| 130| 1
3| 2013-03-28| Profit | 1500| 1630| 1
4 | 2013-03-29| Withdrawals| -700| 930| 1
5| 2013-03-29| Stake | -230 | 700 | 1
6| 2013-04-04| Stake| -150 | 550| 1
7| 2013-04-06| Stake | -150 | 400| 1
What I want now is to get a select statement that gives me all data grouped by week. The result should look like this.
Week|Deposit|Withdrawals|Stake|Profit|Balance|Year
13 | 150| -700 | -250 | 1500 | 700 | 2013
14 | 0 | 0 | -300| 0 | 400 | 2013
I have also problem with the weeks... I live in Europe an my first day in a week is monday. I have a solution for that but around the end of a year I get sometimes week 54 but there are only 52 weeks in a year...
I hope someone can help me out.
This is what I have so far.
SELECT transactionid,
transactiondate,
transactiontype,
amount,
(SELECT Sum(amount)
FROM transactions AS trans_
WHERE trans_.transactiondate <= trans.transactiondate
AND userid = 1) AS Balance,
userid,
Datepart(week, transactiondate) AS Week,
Datepart(year, transactiondate) AS Year
FROM transactions trans
WHERE userid = 1
ORDER BY transactiondate DESC,
transactionid DESC
Here's sample data and my query on sql-fiddle: http://www.sqlfiddle.com/#!3/79d65/92/0
In order to transform the data from the rows into columns, you will want to use the PIVOT function.
You did not specify what balance
value you want to return but based on the final result, it looks like you want the final balance to be the value associated with the last transaction date for each day. If that is not correct, then please clarify what the logic should be.
In order to get the result you will want to use the DATEPART and YEAR functions. These will allow grouping by both the week and year values.
The following query should get the result that you want:
select week,
coalesce(Deposit, 0) Deposit,
coalesce(Withdrawals, 0) Withdrawals,
coalesce(Stake, 0) Stake,
coalesce(Profit, 0) Profit,
Balance,
Year
from
(
select datepart(week, t1.transactiondate) week,
t1.transactiontype,
t2.balance,
t1.amount,
year(t1.transactiondate) year
from transactions t1
cross apply
(
select top 1 balance
from transactions t2
where datepart(week, t1.transactiondate) = datepart(week, t2.transactiondate)
and year(t1.transactiondate) = year(t2.transactiondate)
and t1.userid = t2.userid
order by TransactionId desc
) t2
) d
pivot
(
sum(amount)
for transactiontype in (Deposit, Withdrawals, Stake, Profit)
) piv;
See SQL Fiddle with Demo . The result is:
| WEEK | DEPOSIT | WITHDRAWALS | STAKE | PROFIT | BALANCE | YEAR |
------------------------------------------------------------------
| 13 | 150 | -700 | -250 | 1500 | 700 | 2013 |
| 14 | 0 | 0 | -300 | 0 | 400 | 2013 |
As a side note, you stated that your start of the week is Monday, you might have to use the DATEFIRST function to set the first day of the week.
Another option, without using PIVOT, but rather with few CASEs
WITH CTE AS
(
SELECT
TransactionId
,TransactionDate
,DATEPART(WEEK, TransactionDate) AS Week
,CASE WHEN TransactionType='Deposit' THEN Amount ELSE 0 END AS Deposit
,CASE WHEN TransactionType='Stake' THEN Amount ELSE 0 END AS Stake
,CASE WHEN TransactionType='Profit' THEN Amount ELSE 0 END AS Profit
,CASE WHEN TransactionType='Withdrawals' THEN Amount ELSE 0 END AS Withdrawals
,Balance
,DATEPART(YEAR, TransactionDate) AS Year
FROM dbo.Transactions
)
SELECT
Week, SUM(Deposit) AS Deposit, SUM(Withdrawals) AS Withdrawals, SUM(Stake) AS Stake, SUM(Profit) AS Profit,
(SELECT Balance FROM CTE i WHERE i.TransactionID = MAX(o.TransactionID)) AS BAlance, Year
FROM CTE o
GROUP BY Week, Year
http://www.sqlfiddle.com/#!3/79d65/89
;WITH cte AS
(
SELECT datepart(ww, transactiondate) wk,
sum(CASE WHEN TransactionType = 'Deposit' THEN Amount ELSE 0 END) AS D,
sum(CASE WHEN TransactionType = 'Withdrawals' THEN Amount ELSE 0 END) AS W,
sum(CASE WHEN TransactionType = 'Profit' THEN Amount ELSE 0 END) AS P,
sum(CASE WHEN TransactionType = 'Stake' THEN Amount ELSE 0 END) AS S,
sum(
CASE WHEN TransactionType = 'Deposit' THEN Amount ELSE 0 END +
CASE WHEN TransactionType = 'Withdrawals' THEN Amount ELSE 0 END +
CASE WHEN TransactionType = 'Profit' THEN Amount ELSE 0 END +
CASE WHEN TransactionType = 'Stake' THEN Amount ELSE 0 END +
CASE WHEN TransactionType = 'Balance' THEN Amount ELSE 0 END) AS wkTotal
FROM transactions
GROUP BY datepart(ww, transactiondate)),
cte1 AS
(
SELECT *, row_number() over (ORDER BY wk) AS rowNum
FROM cte)
SELECT wk, d, w, p, s, wktotal
+ coalesce((SELECT top 1 wktotal FROM cte1 x WHERE x.rownum < m.rownum ), 0) AS RunningBalance
FROM cte1 m
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.