How to sum data group by week but sum from beginning? - sql

I have a database like this :
Entry_No Week Registering_Date Bin_Code Item_No Quantity
=====================================================================
1 26 6/26/2015 BIN 1 A 10
2 26 6/26/2015 BIN 1 B 20
3 26 6/26/2015 BIN 1 C 30
4 26 6/26/2015 BIN 1 D 40
5 27 6/29/2015 BIN 1 A -3
6 27 6/29/2015 BIN 2 A 3
7 27 6/29/2015 BIN 1 A -2
8 27 6/29/2015 BIN 3 A 2
9 28 7/5/2015 BIN 1 B -15
10 28 7/5/2015 BIN 3 B 15
11 28 7/5/2015 BIN 1 C -25
12 28 7/5/2015 BIN 2 C 25
13 28 7/5/2015 BIN 1 B 50
And I would like to sum group by BIN_CODE and ITEM_NO by WEEK but from beginning of the data.. I know how to sum group by week but it only shows the summary on that week (not from beginning)
And the result i expect is like this :
WEEK BIN CODE ITEM NO QUANTITY
====================================
26 BIN 1 A 10
26 BIN 1 B 20
26 BIN 1 C 30
26 BIN 1 D 40
26 BIN 2 A -
26 BIN 2 B -
26 BIN 2 C -
26 BIN 2 D -
26 BIN 3 A -
26 BIN 3 B -
26 BIN 3 C -
26 BIN 3 D -
27 BIN 1 A 5
27 BIN 1 B 20
27 BIN 1 C 30
27 BIN 1 D 40
27 BIN 2 A 3
27 BIN 2 B -
27 BIN 2 C -
27 BIN 2 D -
27 BIN 3 A 2
27 BIN 3 B -
27 BIN 3 C -
27 BIN 3 D -
28 BIN 1 A 5
28 BIN 1 B 55
28 BIN 1 C 5
28 BIN 1 D 40
28 BIN 2 A 3
28 BIN 2 B -
28 BIN 2 C 25
28 BIN 2 D -
28 BIN 3 A 2
28 BIN 3 B 15
28 BIN 3 C -
28 BIN 3 D -
Sorry im newbie here to write a good question.. Here is the image :
Could you please help me?
Thanks before :)

Hope this works :
SELECT
t.Week AS WEEK,
t.Bin_Code AS BIN_CODE,
t.Item_No AS ITEM_NO,
SUM(CASE WHEN items.Item_No = t.Item_No THEN items.Quantity ELSE 0 END) AS QUANTITY
FROM your_table as t
CROSS JOIN (SELECT DISTINCT Item_No FROM your_table) AS items
GROUP BY
t.Week,
t.Bin_Code
ORDER BY
1,2,3

Try this query
select Week,Registering_Date,Bin_Code,Item_No, case when asum>0 then asum else '-' end as QUANTITY
from(
select Week,Registering_Date,Bin_Code,Item_No,sum(case when Quantityfrom>0 then quentity else o end ) as asum
from tablename
group by Week,Bin_Code,Item_No)a

Related

sql split yearly record into 12 monthly records

I am trying to use common table expression to split an yearly record into 12 monthly records. I have to do it for next 20 years records . That means 20 rows into 600 rows (20*12=600 records).
What is the best way to do it. Can anyone help with an efficient way to do it.
Using a single table as shown below. Year 0 means current year so it should split into remaining months and year=1 means next year onward it should split into 12 (months) records
id year value
1 0 3155174.87
1 1 30423037.3
1 2 35339631.25
expected result should look like this:
Id Year Month Value Calender year
1 0 5 150 2022
1 0 6 150 2022
1 0 7 150 2022
1 0 8 150 2022
1 0 9 150 2022
1 0 10 150 2022
1 0 11 150 2022
1 0 12 150 2022
1 0 1 150 2023
1 0 2 150 2023
1 0 3 150 2023
1 0 4 150 2023
1 1 5 100 2023
1 1 6 100 2023
1 1 7 100 2023
1 1 8 100 2023
1 1 9 100 2023
1 1 10 100 2023
1 1 11 100 2023
1 1 12 100 2023
1 1 1 100 2024
1 1 2 100 2024
1 1 3 100 2024
1 1 4 100 2024
You can simply join onto a list of months, and then use a bit of arithmetic to split the Value
SELECT
t.Id,
t.Year,
v.Month,
Value = t.Value / CASE WHEN t.Year = 0 THEN 13 - MONTH(GETDATE()) ELSE 12 END
FROM YourTable t
JOIN (VALUES
(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)
) v(Month) ON t.year > 0 OR v.Month >= MONTH(GETDATE());
db<>fiddle

running total starting from a date column

I'm trying to get a running total as of a date. This is the data I have
Date
transaction Amount
End of Week Balance
jan 1
5
100
jan 2
3
100
jan 3
4
100
jan 4
3
100
jan 5
1
100
jan 6
3
100
I would like to find out what the daily end balance is. My thought is to get a running total from each day to the end of the week and subtract it from the end of week balance, like below
Date
transaction Amount
Running total
End of Week Balance
Balance - Running total
jan 1
5
19
100
86
jan 2
3
14
100
89
jan 3
4
11
100
93
jan 4
3
7
100
96
jan 5
1
4
100
97
jan 6
3
3
100
100
I can use
SUM(transactionAmount) OVER (Order by Date)
to get a running total, is there a way to specify that I only want the total of transactions that have taken place after the date?
You can use sum() as a window function, but accumulate in reverse:
select t.*,
(end_of_week_balance -
sum(transactionAmount) over (order by date desc)
)
from t;
If you have this example:
1> select i, sum(i) over (order by i) S from integers where i<10;
2> go
i S
----------- -----------
1 1
2 3
3 6
4 10
5 15
6 21
7 28
8 36
9 45
you can also do:
1> select i, sum(case when i>3 then i else 0 end) over (order by i) S from integers where i<10;
2> go
i S
----------- -----------
1 0
2 0
3 0
4 4
5 9
6 15
7 22
8 30
9 39

Select TOP 1 doesnt return value in case of ex-aequo

this is a link to my data.
I have this query:
SELECT *
FROM tbl c
WHERE C.dep = (select top 1 dep
from tbl cc
where cc.yea = c.yea
and cc.mon = mon
group by mon, yea, dep, n
order by n desc)
OR C.dep =( select top 1 dep
from tbl cc
where cc.yea = c.yea
and cc.mon = mon
group by mon, yea, dep, n
order by n asc
)
ORDER BY yea, mon, n
that sould return for each (month,year) the best (lowest n) and the worst (highest n) dep. This query works for month 1,2,4,5,7 and not for months 3,6. The only difference is that in both 3 and 6 cases I got two del with same score (1). How can I return one of them, instead of not returning anything.
this is my output:
n yea mon dep
----------- ----------- ----------- ----------
1 2017 1 50
48 2017 1 36
58 2017 2 36
85 2017 3 36
1 2017 4 50
39 2017 4 36
1 2017 5 50
39 2017 5 36
19 2017 6 36
3 2017 7 50
17 2017 7 36
And this is how I expected:
n yea. mon dep
----------- ----------- ----------- ----------
1 2017 1 50
48 2017 1 36
58 2017 2 36
85 2017 3 36
1 2017 3 49 (or 67)
1 2017 4 50
39 2017 4 36
1 2017 5 50
39 2017 5 36
1 2017 6 50 (or 13)
19 2017 6 36
3 2017 7 50
17 2017 7 36
Use row_number():
select t.*
from (select t.*,
row_number() over (partition by yea, mon order by n asc) as seqnum_asc,
row_number() over (partition by yea, mon order by n desc) as seqnum_desc
from tbl t
) t
where 1 in (seqnum_asc, seqnum_desc);

Compare Current Row with Previous/Next row in SQL Server

I have a table named team and it like below: I just added a row_number in the 3rd column
RaidNo OutComeID RN
2 15 1
4 15 2
6 14 3
8 16 4
10 16 5
12 14 6
14 16 7
16 15 8
18 15 9
20 16 10
22 12 11
24 16 12
26 16 13
28 16 14
30 15 15
32 14 16
34 13 17
When the OutcomeId came as 16 then start with one and 16 comes consecutively, add one by one. And the results be like
RaidNo OutComeID RN Result
2 15 1 0
4 15 2 0
6 14 3 0
8 16 4 1
10 16 5 2
12 14 6 0
14 16 7 1
16 15 8 0
18 15 9 0
20 16 10 1
22 12 11 0
24 16 12 1
26 16 13 2
28 16 14 3
30 15 15 0
32 14 16 0
34 13 17 0
Help me to get the result.
You can use the following query:
SELECT RaidNo, OutComeID, RN,
CASE
WHEN OutComeID <> 16 THEN 0
ELSE ROW_NUMBER() OVER (PARTITION BY OutComeID, grp ORDER BY RN)
END AS Result
FROM (
SELECT RaidNo, OutComeID, RN,
RN - ROW_NUMBER() OVER (PARTITION BY OutComeID ORDER BY RN) AS grp
FROM mytable) AS t
ORDER BY RN
Field grp identifies slices (also called islands) of consecutive records having the same OutComeID value. The outer query uses grp in order to enumerate each record that belongs to a '16' slice. The records that belong to the other slices are assigned value 0.
Demo here

Using Sum() with multiple where clauses

I'm pretty new to this, so forgive if this has been posted (I had no idea what to even search on).
I have 2 tables, Accounts and Usage
AccountID AccountStartDate AccountEndDate
-------------------------------------------
1 12/1/2012 12/1/2013
2 1/1/2013 1/1/2014
UsageId AccountID EstimatedUsage StartDate EndDate
------------------------------------------------------
1 1 10 1/1 1/31
2 1 11 2/1 2/29
3 1 23 3/1 3/31
4 1 23 4/1 4/30
5 1 15 5/1 5/31
6 1 20 6/1 6/30
7 1 15 7/1 7/31
8 1 12 8/1 8/31
9 1 14 9/1 9/30
10 1 21 10/1 10/31
11 1 27 11/1 11/30
12 1 34 12/1 12/31
13 2 13 1/1 1/31
14 2 13 2/1 2/29
15 2 28 3/1 3/31
16 2 29 4/1 4/30
17 2 31 5/1 5/31
18 2 26 6/1 6/30
19 2 43 7/1 7/31
20 2 32 8/1 8/31
21 2 18 9/1 9/30
22 2 20 10/1 10/31
23 2 47 11/1 11/30
24 2 33 12/1 12/31
I'd like to write one query that gives me estimated usage for each month (starting now until the last month that we serve an account) for all accounts being served during that month.
The results would be as follows:
Month-Year Total Est Usage
------------------------------
Oct-12 0 (none being served)
Nov-12 0 (none being served)
Dec-12 34 (only accountid 1 being served)
Jan-13 23 (accountid 1 & 2 being served)
Feb-13 24 (accountid 1 & 2 being served)
Mar-13 51 (accountid 1 & 2 being served)
...
Dec-13 33 (only accountid 2 being served)
Jan-14 0 (none being served)
Feb-14 0 (none being served)
I'm assuming I need to sum and then do a Group By...but not really sure logically how I'd lay this out.
Revised Answer:
I've created a Months table with columns MonthID, Month with values like (201212, 12), (201301, 1), ...
I've also reorganised the usage table to have a month column rather than the start date and end date, as it makes the idea clearer.
See http://sqlfiddle.com/#!3/f57d84/6 for details
The query is now:
Select
m.MonthID,
Sum(u.EstimatedUsage) TotalEstimatedUsage
From
Accounts a
Inner Join
Usage u
On a.AccountID = u.AccountID
Inner Join
Months m
On m.MonthID Between
Year(a.AccountStartDate) * 100 + Month(a.AccountStartDate) And
Year(a.AccountEndDate) * 100 + Month(a.AccountEndDate) And
m.Month = u.Month
Group By
m.MonthID
Order By
1
Previous answer, for reference which assumed usages ranges were full dates rather than just months.
Select
Year(u.StartDate),
Month(u.StartDate),
Sum(Case When a.AccountStartDate <= u.StartDate And a.AccountEndDate >= u.EndDate Then u.EstimatedUsage Else 0 End) TotalEstimatedUsage
From
Accounts a
Inner Join
Usage u
On a.AccountID = u.AccountID
Group By
Year(u.StartDate),
Month(u.StartDate)
Order By
1, 2