I have the select statement below which is used in a gridview datasource. I need the cumulative column to be calculated on the ProjInstDate like I have below. But if you see the results, I get duplicates on the cumulative totals for the same date, which makes sense. But what I can't figure out is how to have the cumulative be calculated on the ProjInstDate but do it for the different JobIDs. I'm not sure what the select statement is supposed to be like at this point "(t1.ProjectedInstDate >= t2.ProjectedInstDate) ". I know that right here is the issue but I'm not sure how to properly do what I want.
select t1.JobID
, t1.JobName
, t1.[JobDescription]
, t1.JobType
, Convert(varchar, t1.QuoteDate, 101) AS QuoteDate
, t1.ProjectedInstDate
, Convert(decimal(12, 0), t1.QuoteTotal) AS QuoteTotal
, Convert(decimal(12, 0), t1.Prob) AS Prob
, t1.Completed
, t1.ProjectManager
, Convert(decimal(12, 0), t1.ProjectedIncome) AS ProjectedIncome
, sum(CASE WHEN t1.Completed != 'y' and t1.Prob != 0
then Convert(decimal(12, 0),t2.ProjectedIncome)
else null end) As CumulativeProjectedIncome
, Convert(decimal(12, 1), sum(CASE WHEN t1.Completed != 'y' and t1.Prob != 0
then (t2.ProjectedIncome/1923)
else null end)) as DAYSOFWORK
, (CASE WHEN t1.Completed != 'y'and t1.Prob != 0
then Convert(decimal(12, 0), (datediff(day, GetDate(), t1.ProjectedInstDate)))
else null end) AS DAYSFROMTODAY
, (CASE WHEN t1.Completed != 'y' and t1.Prob != 0
then Convert(decimal(12, 1), sum(t2.ProjectedIncome/1923)-datediff(day, GetDate(), t1.ProjectedInstDate))
else null end) as DAYSOFREVASOFTODAY
from ContractPlan t1
inner join
ContractPlan t2
on (t1.ProjectedInstDate >= t2.ProjectedInstDate)
where (t2.Completed = 'n' or t2.Completed = 'N')
and (t1.Completed = 'N' or t1.Completed = 'n')
Group By
t1.JobID
, t1.JobName
, t1.[JobDescription]
, t1.JobType
, t1.QuoteDate
, t1.ProjectedInstDate
, t1.QuoteTotal
, t1.Prob
, t1.ProjectedIncome
, t1.Completed
, t1.ProjectManager
Order By
t1.ProjectedInstDate
ProjInstDate | QuoteTotal | Prob |Comp | PM| ProjectedIncome | CumulativeIncome
2014-04-16 00:00:00 300 100 N NULL 300 300
2014-04-17 00:00:00 6000 100 N NULL 6000 6300
2014-04-18 00:00:00 300 100 N NULL 300 6600
2014-05-01 00:00:00 9756 100 N NULL 9756 63637
2014-05-01 00:00:00 28796 75 N NULL 21597 63637
2014-05-01 00:00:00 11179 50 N NULL 5590 63637
2014-05-01 00:00:00 20094 100 N NULL 20094 63637
2014-05-04 00:00:00 2222 90 N ben 2000 67637
2014-05-04 00:00:00 2222 90 N ben 2000 67637
2014-05-05 00:00:00 23698 100 N daved 23698 98835
2014-05-05 00:00:00 6000 100 N sdf 6000 98835
2014-05-05 00:00:00 1500 100 N NULL 1500 98835
2014-05-07 00:00:00 4500 100 N NULL 4500 103335
2014-05-09 00:00:00 750 100 N NULL 750 104085
2014-05-13 00:00:00 540 100 N NULL 540 104625
Related
I am doing some roster analysis and need to identify when an employee has worked for 5 or more consecutive days. In my table, I can extract data something like the below (note, there are lot more columns, this is just a cut down example):
Emp
Start
First_Entry
1234
23/06/2016
1
1234
24/06/2016
1
1234
24/06/2016
0
1234
25/06/2016
1
1234
26/06/2016
1
1234
27/06/2016
1
1234
28/06/2016
1
1234
29/06/2016
1
1234
29/06/2016
0
1234
30/06/2016
1
1234
2/07/2016
1
1234
3/07/2016
1
1234
3/07/2016
0
1234
4/07/2016
1
1234
4/07/2016
0
1234
5/07/2016
1
1234
6/07/2016
1
1234
9/07/2016
1
1234
10/07/2016
1
1234
11/07/2016
1
1234
12/07/2016
1
And what I am after is something like this:
Emp
Start
First_Entry
Consecutive_Days
Over_5
Status
1234
23/06/2016
1
1
0
Worked < 5
1234
24/06/2016
1
2
0
Worked < 5
1234
24/06/2016
0
2
0
Worked < 5
1234
25/06/2016
1
3
0
Worked < 5
1234
26/06/2016
1
4
0
Worked < 5
1234
27/06/2016
1
5
1
Worked >= 5
1234
28/06/2016
1
6
1
Worked >= 5
1234
29/06/2016
1
7
1
Worked >= 5
1234
29/06/2016
0
7
1
Worked >= 5
1234
30/06/2016
1
8
1
Worked >= 5
1234
02/07/2016
1
1
0
Worked < 5
1234
03/07/2016
1
2
0
Worked < 5
1234
03/07/2016
0
2
0
Worked < 5
1234
04/07/2016
1
3
0
Worked < 5
1234
04/07/2016
0
3
0
Worked < 5
1234
05/07/2016
1
4
0
Worked < 5
1234
06/07/2016
1
5
1
Worked >= 5
1234
09/07/2016
1
1
0
Worked < 5
1234
10/07/2016
1
2
0
Worked < 5
1234
11/07/2016
1
3
0
Worked < 5
1234
12/07/2016
1
4
0
Worked < 5
I'm really not sure how to go about getting the cumulative count for consecutive days, so any help you can give will be amazing
Probably someone would come up with a brilliant solution but this would do. Your problem looks like an "Gaps and Islands" problem. Finding islands of date ranges we can find out the rest easily. In the below SQL, #mindate is not a must, but makes it easier.
CREATE TABLE #temptable
(
[Emp] CHAR(4),
[startDate] DATE,
[First_Entry] BIT
);
INSERT INTO #temptable
(
[Emp],
[startDate],
[First_Entry]
)
VALUES
('1234', N'2016-06-23', 1),
('1234', N'2016-06-24', 1),
('1234', N'2016-06-24', 0),
('1234', N'2016-06-25', 1),
('1234', N'2016-06-26', 1),
('1234', N'2016-06-27', 1),
('1234', N'2016-06-28', 1),
('1234', N'2016-06-29', 1),
('1234', N'2016-06-29', 0),
('1234', N'2016-06-30', 1),
('1234', N'2016-07-02', 1),
('1234', N'2016-07-03', 1),
('1234', N'2016-07-03', 0),
('1234', N'2016-07-04', 1),
('1234', N'2016-07-04', 0),
('1234', N'2016-07-05', 1),
('1234', N'2016-07-06', 1),
('1234', N'2016-07-09', 1),
('1234', N'2016-07-10', 1),
('1234', N'2016-07-11', 1),
('1234', N'2016-07-12', 1);
DECLARE #minDate DATE;
SELECT #minDate = DATEADD(d, -1, MIN(startDate))
FROM #temptable;
WITH firstOnly
AS (SELECT *
FROM #temptable
WHERE First_Entry = 1),
grouper (emp, startDate, grp)
AS (SELECT Emp,
startDate,
DATEDIFF(d, #minDate, startDate) - ROW_NUMBER() OVER (PARTITION BY Emp ORDER BY startDate)
FROM firstOnly),
islands (emp, START, [end])
AS (SELECT emp,
MIN(startDate),
MAX(startDate)
FROM grouper
GROUP BY emp,
grp),
consecutives (emp, startDate, consecutive_days)
AS (SELECT f.Emp,
f.startDate,
-- i.START,
-- i.[end],
ROW_NUMBER() OVER (PARTITION BY f.Emp, i.START ORDER BY i.START)
FROM firstOnly f
INNER JOIN islands i
ON f.startDate
BETWEEN i.START AND i.[end])
SELECT t.Emp,
t.startDate,
t.First_Entry,
c.consecutive_days,
CAST(CASE
WHEN c.consecutive_days < 5 THEN
0
ELSE
1
END AS BIT) Over_5,
CASE
WHEN c.consecutive_days < 5 THEN
'Worked < 5'
ELSE
'Worked >= 5'
END [Status]
FROM consecutives c
INNER JOIN #temptable t
ON t.Emp = c.emp
AND t.startDate = c.startDate;
DROP TABLE #temptable;
This is a island and gap problem, You can try to use LAG window function to get the previous startDate row for each Emp, ten use SUM window function to calculate which days are continuous.
Finally, We can use CASE WHEN expression to judge whether the day is greater than 5.
;WITH CTE AS (
SELECT [Emp],
[startDate],
[First_Entry],
SUM(CASE WHEN DATEDIFF(dd,f_Dt,startDate) <= 1 THEN 0 ELSE 1 END) OVER(PARTITION BY Emp ORDER BY startDate) grp
FROM (
SELECT *,
LAG(startDate,1,startDate) OVER(PARTITION BY Emp ORDER BY startDate) f_Dt
FROM T
) t1
)
SELECT [Emp],
[startDate],
[First_Entry],
SUM(CASE WHEN First_Entry = 1 THEN 1 ELSE 0 END) OVER(PARTITION BY Emp,grp ORDER BY startDate) Consecutive_Days,
(CASE WHEN SUM(CASE WHEN First_Entry = 1 THEN 1 ELSE 0 END) OVER(PARTITION BY Emp,grp ORDER BY startDate) >= 5 THEN 1 ELSE 0 END) Over_5,
(CASE WHEN SUM(CASE WHEN First_Entry = 1 THEN 1 ELSE 0 END) OVER(PARTITION BY Emp,grp ORDER BY startDate) >= 5 THEN 'Worked >= 5' ELSE 'Worked < 5' END) Status
FROM CTE
sqlfiddle
I don't even know what's a good title for this question.
But I'm having a table:
create table trans
(
[transid] INT IDENTITY (1, 1) NOT NULL,
[customerid] int not null,
[points] decimal(10,2) not null,
[date] datetime not null
)
and records:
--cus1
INSERT INTO trans ( customerid , points , date )
VALUES ( 1, 10, '2016-01-01' ) , ( 1, 20, '2017-02-01' ) , ( 1, 22, '2017-03-01' ) ,
( 1, 24, '2018-02-01' ) , ( 1, 50, '2018-02-25' ) , ( 2, 44, '2016-02-01' ) ,
( 2, 20, '2017-02-01' ) , ( 2, 32, '2017-03-01' ) , ( 2, 15, '2018-02-01' ) ,
( 2, 10, '2018-02-25' ) , ( 3, 10, '2018-02-25' ) , ( 4, 44, '2015-02-01' ) ,
( 4, 20, '2015-03-01' ) , ( 4, 32, '2016-04-01' ) , ( 4, 15, '2016-05-01' ) ,
( 4, 10, '2017-02-25' ) , ( 4, 10, '2018-02-27' ) ,( 4, 20, '2018-02-28' ) ,
( 5, 44, '2015-02-01' ) , ( 5, 20, '2015-03-01' ) , ( 5, 32, '2016-04-01' ) ,
( 5, 15, '2016-05-01' ) ,( 5, 10, '2017-02-25' );
-- selecting the data
select * from trans
Produces:
transid customerid points date
----------- ----------- --------------------------------------- -----------------------
1 1 10.00 2016-01-01 00:00:00.000
2 1 20.00 2017-02-01 00:00:00.000
3 1 22.00 2017-03-01 00:00:00.000
4 1 24.00 2018-02-01 00:00:00.000
5 1 50.00 2018-02-25 00:00:00.000
6 2 44.00 2016-02-01 00:00:00.000
7 2 20.00 2017-02-01 00:00:00.000
8 2 32.00 2017-03-01 00:00:00.000
9 2 15.00 2018-02-01 00:00:00.000
10 2 10.00 2018-02-25 00:00:00.000
11 3 10.00 2018-02-25 00:00:00.000
12 4 44.00 2015-02-01 00:00:00.000
13 4 20.00 2015-03-01 00:00:00.000
14 4 32.00 2016-04-01 00:00:00.000
15 4 15.00 2016-05-01 00:00:00.000
16 4 10.00 2017-02-25 00:00:00.000
17 4 10.00 2018-02-27 00:00:00.000
18 4 20.00 2018-02-28 00:00:00.000
19 5 44.00 2015-02-01 00:00:00.000
20 5 20.00 2015-03-01 00:00:00.000
21 5 32.00 2016-04-01 00:00:00.000
22 5 15.00 2016-05-01 00:00:00.000
23 5 10.00 2017-02-25 00:00:00.000
I'm trying to group all the customerid and sum their points. But here's the catch, If the trans is not active for 1 year(the next tran is 1 year and above), the points will be expired.
For this case:
Points for each customers should be:
Customer1 20+22+24+50
Customer2 20+32+15+10
Customer3 10
Customer4 10+20
Customer5 0
Here's what I have so far:
select
t1.transid as transid1,
t1.customerid as customerid1,
t1.date as date1,
t1.points as points1,
t1.rank1 as rank1,
t2.transid as transid2,
t2.customerid as customerid2,
t2.points as points2,
isnull(t2.date,getUTCDate()) as date2,
isnull(t2.rank2,t1.rank1+1) as rank2,
cast(case when(t1.date > dateadd(year,-1,isnull(t2.date,getUTCDate()))) Then 0 ELSE 1 END as bit) as ShouldExpire
from
(
select transid,CustomerID,Date,points,
RANK() OVER(PARTITION BY CustomerID ORDER BY date ASC) AS RANK1
from trans
)t1
left join
(
select transid,CustomerID,Date,points,
RANK() OVER(PARTITION BY CustomerID ORDER BY date ASC) AS RANK2
from trans
)t2 on t1.RANK1=t2.RANK2-1
and t1.customerid=t2.customerid
which gives
from the above table,how do I check for ShouldExpire field having max(rank1) for customer, if it's 1, then totalpoints will be 0, otherwise,sum all the consecutive 0's until there are no more records or a 1 is met?
Or is there a better approach to this problem?
The following query uses LEAD to get the date of the next record withing the same CustomerID slice:
;WITH CTE AS (
SELECT transid, CustomerID, [Date], points,
LEAD([Date]) OVER (PARTITION BY CustomerID
ORDER BY date ASC) AS nextDate,
CASE
WHEN [date] > DATEADD(YEAR,
-1,
-- same LEAD() here as above
ISNULL(LEAD([Date]) OVER (PARTITION BY CustomerID
ORDER BY date ASC),
getUTCDate()))
THEN 0
ELSE 1
END AS ShouldExpire
FROM trans
)
SELECT transid, CustomerID, [Date], points, nextDate, ShouldExpire
FROM CTE
ORDER BY CustomerID, [Date]
Output:
transid CustomerID Date points nextDate ShouldExpire
-------------------------------------------------------------
1 1 2016-01-01 10.00 2017-02-01 1 <-- last exp. for 1
2 1 2017-02-01 20.00 2017-03-01 0
3 1 2017-03-01 22.00 2018-02-01 0
4 1 2018-02-01 24.00 2018-02-25 0
5 1 2018-02-25 50.00 NULL 0
6 2 2016-02-01 44.00 2017-02-01 1 <-- last exp. for 2
7 2 2017-02-01 20.00 2017-03-01 0
8 2 2017-03-01 32.00 2018-02-01 0
9 2 2018-02-01 15.00 2018-02-25 0
10 2 2018-02-25 10.00 NULL 0
11 3 2018-02-25 10.00 NULL 0 <-- no exp. for 3
12 4 2015-02-01 44.00 2015-03-01 0
13 4 2015-03-01 20.00 2016-04-01 1
14 4 2016-04-01 32.00 2016-05-01 0
15 4 2016-05-01 15.00 2017-02-25 0
16 4 2017-02-25 10.00 2018-02-27 1 <-- last exp. for 4
17 4 2018-02-27 10.00 2018-02-28 0
18 4 2018-02-28 20.00 NULL 0
19 5 2015-02-01 44.00 2015-03-01 0
20 5 2015-03-01 20.00 2016-04-01 1
21 5 2016-04-01 32.00 2016-05-01 0
22 5 2016-05-01 15.00 2017-02-25 0
23 5 2017-02-25 10.00 NULL 1 <-- last exp. for 5
Now, you seem to want to calculate the sum of points after the last expiration.
Using the above CTE as a basis you can achieve the required result with:
;WITH CTE AS (
... above query here ...
)
SELECT CustomerID,
SUM(CASE WHEN rnk = 0 THEN points ELSE 0 END) AS sumOfPoints
FROM (
SELECT transid, CustomerID, [Date], points, nextDate, ShouldExpire,
SUM(ShouldExpire) OVER (PARTITION BY CustomerID ORDER BY [Date] DESC) AS rnk
FROM CTE
) AS t
GROUP BY CustomerID
Output:
CustomerID sumOfPoints
-----------------------
1 116.00
2 77.00
3 10.00
4 30.00
5 0.00
Demo here
The tricky part here is to dump all points when they expire, and start accumulating them again. I assumed that if there was only one transaction that we don't expire the points until there's a new transaction, even if that first transaction was over a year ago now?
I also get a different answer for customer #5, as they do appear to have a "transaction chain" that hasn't expired?
Here's my query:
WITH ordered AS (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY customerid ORDER BY [date]) AS order_id
FROM
trans),
max_transid AS (
SELECT
customerid,
MAX(transid) AS max_transid
FROM
trans
GROUP BY
customerid),
not_expired AS (
SELECT
t1.customerid,
t1.points,
t1.[date] AS t1_date,
CASE
WHEN m.customerid IS NOT NULL THEN GETDATE()
ELSE t2.[date]
END AS t2_date
FROM
ordered t1
LEFT JOIN ordered t2 ON t2.customerid = t1.customerid AND t1.transid != t2.transid AND t2.order_id = t1.order_id + 1 AND t1.[date] > DATEADD(YEAR, -1, t2.[date])
LEFT JOIN max_transid m ON m.customerid = t1.customerid AND m.max_transid = t1.transid
),
max_not_expired AS (
SELECT
customerid,
MAX(t1_date) AS max_expired
FROM
not_expired
WHERE
t2_date IS NULL
GROUP BY
customerid)
SELECT
n.customerid,
SUM(n.points) AS points
FROM
not_expired n
LEFT JOIN max_not_expired m ON m.customerid = n.customerid
WHERE
ISNULL(m.max_expired, '19000101') < n.t1_date
GROUP BY
n.customerid;
It could be refactored to be simpler, but I wanted to show the steps to get to the final answer:
customerid points
1 116.00
2 77.00
3 10.00
4 30.00
5 57.00
can you try this:
SELECT customerid,
Sum(t1.points)
FROM trans t1
WHERE NOT EXISTS (SELECT 1
FROM trans t2
WHERE Datediff(year, t1.date, t2.date) >= 1)
GROUP BY t1.customerid
Hope it helps!
try this:
select customerid,Sum(points)
from trans where Datediff(year, date, GETDATE()) < 1
group by customerid
output:
customerid Points
1 - 74.00
2 - 25.00
3 - 10.00
4 - 30.00
I want to find the time duration for each person from one start time. I want to calculate the time duration from 1 start time for each day and multiple end times for multiple users. This is my code:
SELECT *,
CAST(DATEDIFF(n, CAST(End_Time AS datetime),
CAST(Start_Time AS datetime)) AS FLOAT) / 60 AS Time_Duration
FROM
( SELECT NAME,
MAX(CASE WHEN DESCRIPTION = 'Green' THEN Final_Value END) AS Start_Time,
MAX(CASE WHEN DESCRIPTION = 'Red' THEN Final_Value END) AS End_Time
FROM mydata
WHERE NAME != ‘NA’
GROUP BY NAME
) C
I am not able to get any results for time duration.
This is what my output looks like:
Name Start_time End_time Time_Duration
1 Day_1 5/6/15 2:30
2 John 5/6/15 3:30
3 Ben 5/6/15 4:30
4 Mike 5/6/15 5:30
5 Day_2 5/7/15 2:30
6 John_2 5/7/15 4:30
7 Ben_2 5/7/15 5:30
8 Mike_2 5/7/15 6:30
I want it to look like this:
Name Start_time End_time Time_Duration
1 Day_1 5/6/15 2:30
2 John 5/6/15 3:30 1.00
3 Ben 5/6/15 4:30 2.00
4 Mike 5/6/15 5:30 3.00
5 Day_2 5/7/15 2:30
6 John_2 5/7/15 4:30 2.00
7 Ben_2 5/7/15 5:30 3.00
8 Mike_2 5/7/15 6:30 4.00
Assuming that the values in name column has suffix of the day number (and none for day 1)
WITH td AS
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY [day] ORDER BY final_value) rnum
FROM (SELECT *,
CASE WHEN CHARINDEX('_', name) = 0
THEN '1'
ELSE SUBSTRING(name, CHARINDEX('_', name) + 1, LEN(name) - CHARINDEX('_', name))
END [day]
FROM t_dur
) tt
)
SELECT t1.name,
CASE WHEN rnum = 1 THEN t1.final_value END start_time,
CASE WHEN rnum <> 1 THEN t1.final_value END end_time,
CASE CAST(DATEDIFF(hour, (SELECT t2.final_value FROM td t2 WHERE t2.[day] = t1.[day] AND t2.rnum = 1),
t1.final_value) AS DECIMAl(5,2))
WHEN 0 THEN NULL
ELSE CAST(DATEDIFF(hour, (SELECT t2.final_value FROM td t2 WHERE t2.[day] = t1.[day] AND t2.rnum = 1),
t1.final_value) AS DECIMAl(5,2))
END time_duration
FROM td t1
Result
name start_time end_time time_duration
Day_1 2015-05-06 02:30:00.000 NULL NULL
John NULL 2015-05-06 03:30:00.000 1.00
Ben NULL 2015-05-06 04:30:00.000 2.00
Mike NULL 2015-05-06 05:30:00.000 3.00
Day_2 2015-05-07 02:30:00.000 NULL NULL
John_2 NULL 2015-05-07 04:30:00.000 2.00
Ben_2 NULL 2015-05-07 05:30:00.000 3.00
Mike_2 NULL 2015-05-07 06:30:00.000 4.00
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
I have a table that holds data about class entries for a certain journal. I'm trying to separate the results by week so I get a count of those entries per week. But when I group by day, I get null values too. I want to omit records with Null Values. How do I do that?
I wrote the following code:
SELECT Year(JournalDate) AS YY
,Month(JournalDate) AS MM
,FromClass
,ToClass
,(SELECT Count(JournalID)
WHERE Day(JournalDate) >= 1 AND Day(JournalDate)=7) AS CountWeek1
,(SELECT Count(JournalID)
WHERE Day(JournalDate) >= 8 AND Day(JournalDate)=14) AS CountWeek2
,(SELECT Count(JournalID)
WHERE Day(JournalDate) >= 15 AND Day(JournalDate)=21) AS CountWeek3
,(SELECT Count(JournalID)
WHERE Day(JournalDate) >= 22 AND Day(JournalDate)=28) AS CountWeek4
,(SELECT Count(JournalID)
WHERE Day(JournalDate) >= 29 AND Day(JournalDate)=31) AS CountWeek5
FROM [tblJournal]
WHERE [JournalDate] >= '2016-09-01 00:00:00.000'
AND FromClass <> ToClass
--AND CountWeek1 IS NOT Null
GROUP BY Year(JournalDate), Month(JournalDate), Day( JournalDate), FromClass, ToClass
ORDER BY YY, MM, FromClass, ToClass
But I get Null values too. I want to remove Null Values.
YY MM FrClass ToClass CntWk1 CntWk2 CntWk3 CntWk4 CntWk5
2016 9 1 2 NULL NULL NULL NULL NULL
2016 9 1 2 NULL NULL NULL NULL NULL
2016 9 1 2 NULL NULL NULL NULL NULL
2016 9 1 2 NULL NULL NULL NULL NULL
2016 9 1 2 NULL 20 NULL NULL NULL
2016 9 1 2 NULL NULL NULL NULL NULL
2016 9 1 2 NULL NULL NULL NULL NULL
2016 9 1 2 NULL NULL NULL NULL NULL
2016 9 1 2 NULL NULL NULL NULL NULL
2016 9 1 2 NULL NULL NULL NULL NULL
2016 9 1 2 NULL NULL NULL NULL NULL
2016 9 1 2 12 NULL NULL NULL NULL
2016 9 1 2 NULL NULL NULL NULL NULL
2016 9 1 2 NULL NULL NULL NULL NULL
2016 9 1 2 NULL NULL NULL NULL NULL
2016 9 1 2 NULL NULL NULL NULL NULL
2016 9 1 2 NULL NULL 29 NULL NULL
2016 9 1 2 NULL NULL NULL NULL NULL
2016 9 1 2 NULL NULL NULL NULL NULL
2016 9 1 2 NULL NULL NULL 25 NULL
How do I omit the records with NULL values?
EDIT:
So I would actually like my results to look like this:
YY MM FrmCls ToClsWk1 Wk2 Wk3 Wk4 Wk5
2016 9 1 2 12 20 29 25 0
2016 9 1 3 2 1 6 0 0
2016 9 1 4 0 1 2 0 0
2016 9 2 1 0 3 0 2 0
2016 9 2 3 74 46 84 54 0
2016 9 2 4 0 0 8 5 0
2016 9 3 2 0 813 0 0 0
Take your data above and insert into a temp table. After that you can query on your result by suming data by year, month, etc. like this:
SELECT YY, MM, FrClass,ToClass,SUM(cntwk1),SUM(cntwk2),SUM(cntwk3),SUM(cntwk4),SUM(cntwk5)
FROM #data
GROUP BY YY, MM, FrClass,ToClass
how about this
select * from
(
SELECT Year(JournalDate) AS YY
,Month(JournalDate) AS MM
,FromClass
,ToClass
,isnull((SELECT Count(JournalID)
WHERE Day(JournalDate) >= 1 AND Day(JournalDate)=7),0) AS CountWeek1
,isnull((SELECT Count(JournalID)
WHERE Day(JournalDate) >= 8 AND Day(JournalDate)=14),0) AS CountWeek2
,isnull((SELECT Count(JournalID)
WHERE Day(JournalDate) >= 15 AND Day(JournalDate)=21),0) AS CountWeek3
,isnull((SELECT Count(JournalID)
WHERE Day(JournalDate) >= 22 AND Day(JournalDate)=28),0) AS CountWeek4
,isnull((SELECT Count(JournalID)
WHERE Day(JournalDate) >= 29 AND Day(JournalDate)=31),0) AS CountWeek5
FROM [tblJournal]
WHERE [JournalDate] >= '2016-09-01 00:00:00.000'
AND FromClass <> ToClass
GROUP BY Year(JournalDate), Month(JournalDate), Day( JournalDate), FromClass, ToClass
) x
where CountWeek1 +CountWeek2+CountWeek3+CountWeek4+CountWeek5 <> 0
ORDER BY YY, MM, FromClass, ToClass