Query for Dedit/Credit Transactions - sql

Here is Query I am using :
select Date2,
sum(case when Type='Debit' then Amount else 0 end)as DebitAmount,
sum(case when Type='Credit' then Amount else 0 end)as CreditAmount,
((sum(case when Type='Debit' then Amount else 0 end))-sum(case when Type='Credit' then Amount else 0 end)) as Balance
from MainTransaction
group by MainTransaction.Date2
order by Date2
OutPut :
Date | Debit | Credit | Balance
-----------+---------+--------+-----------
2015-02-10 | 0.0 | 0 | 0.0
2015-02-12 | 19200.0 | 0 | 19200.0
2015-03-01 | 62000.0 | 0 | 62000.0
2015-03-08 | 999.0 | 0 | 999.0
2015-03-09 | 10064.0 | 0 | 10064.0
What I want it to display total balance as well , I mean like date is 11.03.2015 it will also display total debit till date 11.03.2015 -credit till date 11.03.2015..
What should I do .. I simply can't do sum as I am using group by date2..

Set {0} = '2015-03-11'
select ifnull(mt.Date2, mt.Date2s),
sum(case when mt.Type='Debit' then mt.Amount else 0 end)as DebitAmount,
sum(case when mt.Type='Credit' then mt.Amount else 0 end)as CreditAmount,
((sum(case when mt.Type='Debit' then mt.Amount else 0 end))-sum(case when mt.Type ='Credit' then mt.Amount else 0 end)) as Balance
from (
select mt.*, sd.*
from MainTransaction as mt
left join
(select {0} as Date2s) as sd On mt.date2 = sd.Date2s
where mt.date2 < {0}
union all
select mt.*, sd.*
from (select {0} as Date2s) as sd
left join
MainTransaction as mt On mt.date2 = sd.Date2s
where mt.date2 is null
) as mt
group by ifnull(mt.Date2, mt.Date2s)
order by ifnull(mt.Date2, mt.Date2s)

Related

Average call volumes between times , total for months

Table Calls c
CALL_ID | CALL_START | CONTACT_ID | CALL_TYPE
--------------------------------------------------
2 | 25/11/2010 11:28:16 | 850 | I
3 | 25/11/2010 11:28:57 | 850 | I
5 | 29/11/2010 10:18:44 | 848 | I
Table Contacts ct
CONTACT_ID | COMPANY_ID | RECORD_STATUS
-----------------------------------
1 | 1 | A
19 | 2 | A
20 | 3 | A
21 | 4 | A
22 | 5 | A
I want to extract the number of Incoming and Outgoing calls per month
For one particular Company_id and for all the others.
I also need to have the average number of calls between 0700 and 1500 / 1500 and 2200 / 2200 0700
All starts from October 2016 and I have a list of operator's ID to include...
select
extract(year from c.call_start) as MyYear,
extract(month from c.call_start) as MyMonth,
count(case when call_type='I' and ct.Company_id not like 391 then 1 else null end) as Incoming_Main,
count(case when call_type='O' and ct.Company_id not like 391 then 1 else null end) as Outgoing_Main,
count(case when call_type='I' and ct.Company_id = 391 then 1 else null end) as Incoming_SMG,
count(case when call_type='O' and ct.Company_id = 391 then 1 else null end) as Outgoing_SMG,
SUM(CASE WHEN CAST(c.CALL_START AS TIME) BETWEEN '07:00:00' and '15:00:00' and ct.company_id=391 THEN 1 ELSE 0 END)/31 Am391,
SUM(CASE WHEN CAST(c.CALL_START AS TIME) BETWEEN '07:00:00' and '15:00:00' and ct.company_id not like 391 ELSE 0 END)/31 AmMAIN,
SUM(CASE WHEN CAST(c.CALL_START AS TIME) BETWEEN '15:00:00' and '22:00:00' and ct.company_id =391 THEN 1 ELSE 0 END)/31 PM391,
SUM(CASE WHEN CAST(c.CALL_START AS TIME) BETWEEN '15:00:00' and '22:00:00' and ct.company_id=391 THEN 1 ELSE 0 END)/31 PmMAIN,
SUM(CASE WHEN CAST(c.CALL_START AS TIME) BETWEEN '07:00:00' and '15:00:00' and ct.company_id=391 THEN 1 ELSE 0 END)/31 Am391,
SUM(CASE WHEN CAST(c.CALL_START AS TIME) BETWEEN '07:00:00' and '15:00:00' and ct.company_id=391 THEN 1 ELSE 0 END)/31 Am391,
from
CALLS c
left outer join CONTACTS ct on c.CONTACT_ID= ct.CONTACT_ID
where ct.RECORD_STATUS='A'
and c.OPERATOR_ID in (1,19,22)
and c.call_start >='2016/10/01

How to count sql from one column, and display it in two column

I have a table like this:
idrecord | date
----------------------------------------------
INC-20140308102029 | 2014-03-08 00:00:00.000
INC-20140308102840 | 2014-03-06 00:00:00.000
INC-20140310164404 | 2014-03-10 00:00:00.000
INC-20140311075714 | 2014-03-09 00:00:00.000
NRM-20140310130512 | 2014-04-02 00:00:00.000
NRM-20140311134720 | 2014-03-11 00:00:00.000
USF-20140317212232 | 2014-03-17 00:00:00.000
USF-20140321075402 | 2014-03-18 00:00:00.000
USF-20140321083137 | 2014-03-21 00:00:00.000
how to count this table and display result like this:
month | INC | NRM | USF
march | 4 | 1 | 3
April | 0 | 1 | 0
Thank you
You'd use case to count 1 or zero depending on the string matching or not. Use sum to count.
select
extract(month from thedate) as whichmonth,
sum( case when idrecord like 'INC%' then 1 else 0 end) as inc,
sum( case when idrecord like 'NRM%' then 1 else 0 end) as nrm,
sum( case when idrecord like 'USF%' then 1 else 0 end) as usf
from mytable
group by extract(month from thedate);
The function to extract the month from the date may vary from dbms to dbms. Look the appropriate function up in Google, if extract doesn't work for you.
Don't use the name date for a column. Date is a reserved word in SQL.
Try this
SELECT convert(char(3), date, 0) AS Month,
SUM(Case when LEFT(idrecord,3) = 'INC' then 1 else 0 end) as 'INC',
SUM(Case when LEFT(idrecord,3) = 'NRM' then 1 else 0 end) as 'NRM',
SUM(Case when LEFT(idrecord,3) = 'USF' then 1 else 0 end) as 'USF'
FROM Table1
Group By convert(char(3), date, 0)
Fiddle Demo
or:
SELECT datename(mm, date) AS Month,
SUM(Case when LEFT(idrecord,3) = 'INC' then 1 else 0 end) as 'INC',
SUM(Case when LEFT(idrecord,3) = 'NRM' then 1 else 0 end) as 'NRM',
SUM(Case when LEFT(idrecord,3) = 'USF' then 1 else 0 end) as 'USF'
FROM Table1
Group By datename(mm, date)
Fiddle Demo
Output:
month | INC | NRM | USF
march | 4 | 1 | 3
April | 0 | 1 | 0
try this one
select month (date) as month,
count( case when idrecord like 'INC%' then 1 else 0 end) as inc,
count( case when idrecord like 'NRM%' then 1 else 0 end) as nrm,
count( case when idrecord like 'USF%' then 1 else 0 end) as usf
from table
group by month;

SQL query to calculate total per month as a column

I am stuck on a SQL query. I am using PostgreSQL. I need to get the total for each month for all states.
table A
--------------------------------------------------------
created | Name | Agent_id | Total
--------------------------------------------------------
3/14/2013 | Harun | 1A | 5
3/14/2013 | Hardi | 2A | 20
4/14/2013 | Nizar | 3A | 30
5/14/2013 | moyes | 4A | 20
table B
----------------------------
Agent_id| state_id
----------------------------
1A | 1
2A | 1
3A | 1
4A | 2
table C
----------------------------
state_id | State
----------------------------
1 | Jakarta
2 | Singapore
3 | Kuala lumpur
DESIRED RESULT:
-----------------------------------------------------------------------------------------------
No |State | Januari | February | March | April | Mei ... December| Total
-----------------------------------------------------------------------------------------------
1 |Jakarta |0 |0 |25 | 30 | 0 ... | 55
2 |Singapore |0 |0 | 0 | 0 | 20 ... | 20
3 |Kuala Lumpur |0 |0 | 0 | 0 | 0 ... | 0
to have all state with no data in table A / B you have to use OUTER JOIN
to complete #bma answer
select
no,
state,
sum(case when month = 1 then total else 0 end) as januari,
sum(case when month = 2 then total else 0 end) as februari,
sum(case when month = 3 then total else 0 end) as mars,
sum(case when month = 4 then total else 0 end) as april,
sum(case when month = 5 then total else 0 end) as may,
sum(case when month = 6 then total else 0 end) as juni,
sum(case when month = 7 then total else 0 end) as juli,
sum(case when month = 8 then total else 0 end) as august,
sum(case when month = 9 then total else 0 end) as september,
sum(case when month = 10 then total else 0 end) as october,
sum(case when month = 11 then total else 0 end) as november,
sum(case when month = 12 then total else 0 end) as december,
sum(coalesce(total,0)) as total
from (
select
c.state_id as no,
extract(month from created) as month,
state,
sum(total) as total
from tablec c
left join tableb b on ( b.state_id = c.state_id)
left join tablea a on ( a.agent_id = b.agent_id)
group by c.state_id,state,month
) sales
group by no,state;
SQL Fiddle demo
Actually i do not know much about postgres sql this is a try see if this works
try this
Select EXTRACT(MONTH FROM TIMESTAMP table A.created) ,
table C.State , SUM(Total) From table A , table B , table C
Where table A.Agent_id = table B.Agent_id
And table B.state_id = table C.state_id
Group by table C.State , EXTRACT(MONTH FROM TIMESTAMP table A.created);
Something like the following should give you results like your sample results. I'm not sure what the "No" column was though. This query is untested.
select state,
sum(case when mm = 1 then total else 0 end) as jan,
sum(case when mm = 2 then total else 0 end) as feb,
sum(case when mm = 3 then total else 0 end) as mar,
sum(case when mm = 4 then total else 0 end) as apr,
sum(case when mm = 5 then total else 0 end) as may,
sum(case when mm = 6 then total else 0 end) as jun,
sum(case when mm = 7 then total else 0 end) as jul,
sum(case when mm = 8 then total else 0 end) as aug,
sum(case when mm = 9 then total else 0 end) as sep,
sum(case when mm = 10 then total else 0 end) as oct,
sum(case when mm = 11 then total else 0 end) as nov,
sum(case when mm = 12 then total else 0 end) as dec,
sum(total) as total
from (
select extract(month from created) as mm,
state,
sum(total) as total
from table_a
group by state,mm
) s
group by state;

Combine data from a table to one row T-SQL

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
SQLFiddle Demo
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

How to separate positive and negative numbers into their own columns?

I have a table with the following columns and data:
activity_dt | activity_amt
2009-01-01 | -500
2009-01-01 | 750
Can I write a query that looks at the sign of activity_amt and puts it in the credits column if it's positive, and the debits column if it's negative? (I'm using Sybase)
activity_dt | debits | credits
2009-01-01 | -500 | 750
select activity_dt,
sum(case when activity_amt < 0 then activity_amt else 0 end) as debits,
sum(case when activity_amt > 0 then activity_amt else 0 end) as credits
from the_table
group by activity_dt
order by activity_dt
I'm not sure about the exact syntax in Sybase, but you should be able to group on the date and sum up the positive and negative values:
select
activity_dt,
sum(case when activity_amt < 0 then activity_amt else 0 end) as debits,
sum(case when activity_amt >= 0 then activity_amt else 0 end) as credits
from
theTable
group by
activity_dt
I found a new answer to this problem using the DECODE function.
I hope this turns out to be useful for everyone.
select activity_dt,
sum((DECODE(activity_amt /-ABS(activity_amt), 1, activity_amt, 0))) as credits,
sum((DECODE(activity_amt /-ABS(activity_amt), -1, activity_amt, 0))) as debits
from the_table
group by activity_dt
order by activity_dt;
select (select JV_GroupsHead.GroupTitle
from JV_GroupsHead
whereJV_GroupsHead.Id=jv.GroupId) as 'GroupName'
,jv.Revenue
,jv.AccountNo
,jv.AccountNoTitle
,(case when jv.Revenue < 0 then jv.Revenue else 0 end) as 'debits'
,(case when jv.Revenue> 0 then jv.Revenue else 0 end) as 'credits'
from JVFunction1('2010-07-08','2010-08-08') as jv