I have a table structure like the following
TNO DATE NETAMT CHQ CASH PARTY
---------------------------------------------
T1 01/04/2016 100 10 0 TEST1
T2 15/04/2016 50 0 0 TEST2
T3 18/04/2016 100 100 0 TEST3
Now I want to make a SQL query which will give me an aging report of which transactions are lying outstanding in which slabs.
I want to see the result in the following format
PARTY 0-3 DAYS 4-6 DAYS 7-15 DAYS
---------------------------------------------
TEST1 0 0 90
TEST2 0 50 0
TEST3 0 0 0
Try this
SELECT PARTY,
SUM(CASE WHEN DATEDIFF(DAY,[DATE],GETDATE()) BETWEEN 0 AND 3 THEN (NETAMT - CHQ) ELSE 0 END) AS [0_3_DAYS],
SUM(CASE WHEN DATEDIFF(DAY,[DATE],GETDATE()) BETWEEN 4 AND 6 THEN (NETAMT - CHQ) ELSE 0 END) AS [4_6_DAYS],
SUM(CASE WHEN DATEDIFF(DAY,[DATE],GETDATE()) BETWEEN 7 AND 15 THEN (NETAMT - CHQ) ELSE 0 END) AS [7_15_DAYS],
FROM TABLE1
GROUP BY PARTY
Related
I am working with a dataset that contains information about train delays. The dataset contains an arrival delay column and departing delay column. Each delay column is measured in minutes. I need to calculate the number of total delays for each day of the week to determine which day has the most train delays. If the delay is equal to or more than 1 minute, it needs to be counted as a delay. How can I complete this in SQL? I have tried the following code.
select dayofweek
count(case when arrivaldelay>=1 then 1 end)+
count(case when departuredelay>=1 then 1 end)
group by dayofweek;
dayofweek arrivaldelay departuredelay
2 12 5
4 7 10
4 6 -3
6 5 4
dayofweek delays
2 1
4 1
6 1
Assuming dayofweek is a stored column and not a function, then you can use either count or sum
select
dayofweek
, count(case when arrivaldelay >= 1 then 1 end)
+ count(case when departuredelay >= 1 then 1 end)
as delays
from mytable as t
group by dayofweek;
select
dayofweek
, sum(case when arrivaldelay >= 1 then 1 else 0 end)
+ sum(case when departuredelay >= 1 then 1 else 0 end)
as delays
from mytable as t
group by dayofweek;
both give the following result from the sample data in the question
+-----------+--------+
| dayofweek | delays |
+-----------+--------+
| 2 | 2 |
| 4 | 3 |
| 6 | 2 |
+-----------+--------+
IF dayofweek is NOT a stored column then you can extract the day of week from a date or timestamp, BUT there are differences in how this is achieved in different databases
demonstrated #db<>fiddle here
You can use sum() like this:
select dayofweek
( sum(case when arrivaldelay >= 1 then 1 else 0 end)+
sum(case when departuredelay >= 1 then 1 else 0 end)
)
from t
group by dayofweek;
I am relatively new to SQL. I have a dataset as follows:
'ID' 'date'
1 2016-01-01 01:01:06
2 2016-01-02 02:02:07
1 2016-01-03 03:03:08
3 2016-04-04 04:04:09
2 2016-04-05 05:05:00
I want to obtain smth like this:
'ID' 'Count: Jan' 'Count: Feb' 'Count: March' 'Count: April'
1 2 0 0 0
2 1 0 1 0
3 0 0 0 1
I really have no idea how handle this. I could put the data creating a column "month" and another column "count" but I want to be able to have a table like this.
Thanks in advance
You ca use conditional aggregation:
select id,
sum(case when month(date) = 1 then 1 else 0 end) as cnt_jan,
sum(case when month(date) = 2 then 1 else 0 end) as cnt_feb,
. . .
sum(case when month(date) = 12 then 1 else 0 end) as cnt_dec
from t
group by id;
I create a table using the command below:
CREATE TABLE IF NOT EXISTS stats (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
session_kind INTEGER NOT NULL,
ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
)
I insert some time series data using the command below:
INSERT INTO stats (session_kind) values (?1)
Some time after having executed several times the insert command, I have some time series data as below:
id session_kind ts
-----------------------------------------
1 0 2020-04-18 12:59:51 // day 1
2 1 2020-04-19 12:59:52 // day 2
3 0 2020-04-19 12:59:53
4 1 2020-04-19 12:59:54
5 0 2020-04-19 12:59:55
6 2 2020-04-19 12:59:56
7 2 2020-04-19 12:59:57
8 2 2020-04-19 12:59:58
9 2 2020-04-19 12:59:59
10 0 2020-04-20 12:59:51 // day 3
11 1 2020-04-20 12:59:52
12 0 2020-04-20 12:59:53
13 1 2020-04-20 12:59:54
14 0 2020-04-20 12:59:55
15 2 2020-04-20 12:59:56
16 2 2020-04-20 12:59:57
17 2 2020-04-20 12:59:58
18 2 2020-04-21 12:59:59 // day 4
What I would like to have a command that groups my data by date from the most recent day to the least and the number of each session_kind like below (I don't want to give any parameter to this command):
0 1 2 ts
-------------------------
0 0 1 2020-04-21 // day 4
3 2 3 2020-04-20 // day 3
2 2 4 2020-04-19 // day 2
1 0 0 2020-04-18 // day 1
How can I group my data as above?
You can do conditional aggregation:
select
sum(session_kind= 0) session_kind_0,
sum(session_kind= 1) session_kind_1,
sum(session_kind= 2) session_kind_2,
date(ts) ts_day
from mytable
group by date(ts)
order by ts_day desc
If you want something dynamic, then it might be simpler to put the results in rows rather than columns:
select date(ts) ts_day, session_kind, count(*) cnt
from mytable
group by date(ts), session_kind
order by ts_day desc, session_kind
If I understand correctly, you just want to sum the values:
select date(timestamp),
sum(case when session_kind = 1 then 1 else 0 end) as cnt_1,
sum(case when session_kind = 2 then 1 else 0 end) as cnt_2,
sum(case when session_kind = 3 then 1 else 0 end) as cnt_3
from t
group by date(timestamp);
You can also simplify this:
select date(timestamp),
sum( session_kind = 1 ) as cnt_1,
sum( session_kind = 2 ) as cnt_2,
sum( session_kind = 3 ) as cnt_3
from t
group by date(timestamp);
I'm still learning SQL and I'm trying to figure out a problem that I wasn't able to solve. So my problem is that I'm trying to select a table(let say Expense), ordered by date and in the table I have a column named Charged and I want to add charges to be cumulative(This part I figured out). However after that I have another column that will be acting as a flag called PayOut. When the PayOut value is 1 I want the summation of Charged(SumValue) to reset to zero. How would I do this? Here is what I have tried and the current output I get and what output I want. Note: I saw some posts using CTE's but wasn't the same scenario and more complex.
select ex.date,
ex.Charged,
(case when(ex.PayOut=1) then 0
else sum(ex.Charged) over (order by ex.date)end) as SumValue,
ex.PayOut
from Expense ex
order by ex.date asc
The data looks like this
Date Charged PayOut
01/10/2018 10 0
01/20/2018 5 0
01/30/2018 3 0
02/01/2018 0 1
02/11/2018 12 0
02/21/2018 15 0
Output I get
Date Charged PayOut SumValue
01/10/2018 10 0 10
01/20/2018 5 0 15
01/30/2018 3 0 18
02/01/2018 0 1 0
02/11/2018 12 0 30
02/21/2018 15 0 45
Output Wanted
Date Charged PayOut SumValue
01/10/2018 10 0 10
01/20/2018 5 0 15
01/30/2018 3 0 18
02/01/2018 0 1 0
02/11/2018 12 0 12
02/21/2018 15 0 27
Just create group from your PayOut Column and use it as a partition in OVER
WITH Expense AS (
SELECT CAST('01/10/2018' AS DATE) AS Date, 10 AS Charged, 0 AS PayOut
UNION ALL SELECT CAST('01/20/2018' AS DATE), 5, 0
UNION ALL SELECT CAST('01/30/2018' AS DATE), 3, 0
UNION ALL SELECT CAST('02/01/2018' AS DATE), 0, 1
UNION ALL SELECT CAST('02/11/2018' AS DATE), 12, 0
UNION ALL SELECT CAST('02/21/2018' AS DATE), 15, 0
)
SELECT
dat.date
,dat.Charged
,dat.PayOut
,dat.PayOutGroup
,SUM(dat.Charged) OVER (PARTITION BY dat.PayOutGroup ORDER BY dat.date) as SumValue
FROM (
SELECT
e.date
,e.Charged
,e.PayOut
,SUM(e.PayOut) OVER (ORDER BY e.date) AS PayOutGroup
FROM Expense e
) dat
I am extracting data out of SQL database and need to calculate the opening balance of a stock item per project. I am getting the opening balance for the stock inclusive of all the projects.
item code | Project | Qty In | Qty Out
----------+---------+--------+---------
1234 1 0 90
1234 1 90 0
1234 2 431 0
1234 2 0 22
1234 3 925 0
1234 3 0 925
1234 3 925 0
1234 3 0 20
1234 3 0 40
1234 3 0 30
1234 3 0 40
1234 3 0 60
1234 3 0 50
1234 3 0 24
1234 3 0 40
1234 3 0 30
1234 3 0 17
1234 3 0 80
1234 3 0 30
1234 4 16 0
1234 4 0 16
1234 5 22 0
1234 5 0 23
Query:
select OpeningBalanceQty = Qty_On_Hand +
(select case when ServiceItem = 0
then IsNull(sum (QtyOut), 0)
else 0
end
from table1
where AccountLink=StockLink and txdate>='2016-06-01' and project ='2' ) -
(select case when ServiceItem = 0
then IsNull(sum (QtyIn), 0)
else 0
end from table1
where AccountLink=StockLink and txdate>='2016-06-01' and project ='2')
from tablel join table2 on table1.AccountLink = table2.StockLink
I have used project 2 as an example, it has two transactions(qty in:431)& (qty out:22)
My opening balance should be 409 but it is giving the total for the product item
My full code:
select Table1.TxDate,Table2.Pack,Table1.Reference,
OpeningBalanceQty= (select case when ServiceItem = 0 then IsNull(sum
(QtyOut), 0) else 0 end from Table1 where AccountLink=StockLink and
ProjectCode in('2') ) - (select case when ServiceItem = 0 then IsNull(sum
(QtyIn), 0) else 0 end from Table1 where AccountLink=StockLink and
ProjectCode in('2'))
,ProjectCode,ProjectDescription, Code, Description_1, Sum(ActualQuantity)*-1
as [Qty Processed],Sum(Debit)-Sum(Credit) as [Value],Trcode
from Table1
join Table2
on Table1 .AccountLink = Table2.StockLink
where ServiceItem = 0 and txdate>='2017-06-01 00:00:00' and txdate<='2017-
06-30 00:00:00' and Code='1234'
Group by Description_1, Code,ProjectCode, ProjectDescription, stocklink,
serviceitem,Qty_On_Hand,Table1.Reference,Table2.Pack,Table1.TxDate,trcode
Do you think this could be helpful for you?
SELECT PROJECT, SUM( QTYIN-QTYOUT) AS OPEN_BAL_QTY
FROM yourtable
WHERE txdate>='2016-06-01'
GROUP BY PROJECT
Output:
PROJECT OPEN_BAL_QTY
1 0
2 409
3 464
4 0
5 -1
1° update: after your new information (pls, next time, try to give all the information in your initial post, and well formatted: see tour of stackoverflow to learn how to do).
If you are using MSSQL 2005 or later, you can try this:
SELECT TABLE1.TXDATE
,TABLE2.PACK
,TABLE1.REFERENCE
, SUM(QTYIN-QTYOUT) OVER (PARTITION BY TABLE1.PROJECTCODE) AS OPEN_BAL_QTY
,PROJECTCODE
,PROJECTDESCRIPTION
,CODE
,DESCRIPTION_1
,-SUM(ACTUALQUANTITY) AS QTY PROCESSED
, SUM(DEBIT) - SUM(CREDIT) AS VALUE
,TRCODE
FROM TABLE1
JOIN TABLE2 ON TABLE1.ACCOUNTLINK = TABLE2.STOCKLINK
WHERE SERVICEITEM = 0
AND TXDATE >= '2017-06-01 00:00:00'
AND TXDATE <= '2017-06-30 00:00:00'
AND CODE = '1234'
GROUP BY DESCRIPTION_1
,CODE
,PROJECTCODE
,PROJECTDESCRIPTION
,STOCKLINK
,SERVICEITEM
,QTY_ON_HAND
,TABLE1.REFERENCE
,TABLE2.PACK
,TABLE1.TXDATE
,TRCODE
2° update
If it doesn't work for you, you should try:
SELECT A.*
,B.OPEN_BAL_QTY
FROM
SELECT TABLE1.TXDATE
,TABLE2.PACK
,TABLE1.REFERENCE
,PROJECTCODE
,PROJECTDESCRIPTION
,CODE
,DESCRIPTION_1
,-SUM(ACTUALQUANTITY) AS QTY PROCESSED
, SUM(DEBIT) - SUM(CREDIT) AS VALUE
,TRCODE
FROM TABLE1
JOIN TABLE2 ON TABLE1.ACCOUNTLINK = TABLE2.STOCKLINK
WHERE SERVICEITEM = 0
AND TXDATE >= '2017-06-01 00:00:00'
AND TXDATE <= '2017-06-30 00:00:00'
AND CODE = '1234'
GROUP BY DESCRIPTION_1
,CODE
,PROJECTCODE
,PROJECTDESCRIPTION
,STOCKLINK
,SERVICEITEM
,QTY_ON_HAND
,TABLE1.REFERENCE
,TABLE2.PACK
,TABLE1.TXDATE
,TRCODE
) A
LEFT JOIN (SELECT PROJECTCODE, SUM( QTYIN-QTYOUT) AS OPEN_BAL_QTY
FROM TABLE1
WHERE TXDATE>='2017-06-01'
AND TXDATE <= '2017-06-30 00:00:00'
GROUP BY PROJECT) B ON A.PROJECT_CODE = B.PROJECT_CODE