SQL to SUM numbers WHEN ITEM number is the same - sql

Trying to work on SUM SQL code to SUM SOH for all ITEM_PARENT numbers. SOH is the result I'm looking for and ITEM_PARENT and STOCK_ON_HAND is what I have.
CASE WHEN ITEM_PARENT = ITEM_PARENT THEN SUM(STOCK_ON_HAND) ELSE 'DN' END AS SOH_SUM,
The code I have already done seems to be not working....
ITEM_PARENT STOCK_ON_HAND SOH_SUM
123649336 1 11
123649336 1 11
123649336 1 11
123649336 5 11
123649336 2 11
123649336 1 11
123649328 1 15
123649328 1 15
123649328 2 15
123649328 1 15
123649328 2 15
123649328 1 15
123649328 1 15
123649328 3 15
123649328 3 15
124566152 3 19
124566152 1 19
124566152 3 19
124566152 3 19
124566152 2 19
124566152 7 19
Anyone know what I'm missing there?

It looks as though you trying to do some sort of conditional aggregation, but your expected output does not require this. We can just do a select over the entire table and then use SUM as an analytic function to compute the SOH_SUM.
SELECT
ITEM_PARENT, STOCK_ON_HAND,
SUM(STOCK_ON_HAND) OVER (PARTITION BY ITEM_PARENT) SOH_SUM
FROM yourTable
ORDER BY ITEM_PARENT;

You can use window functions to get the desired result.
select
[ITEM_PARENT]
,[STOCK_ON_HAND]
,sum([STOCK_ON_HAND]) over(partition by [ITEM_PARENT]) as [ItemTotal]
from tablename
;
Otherwise, if you wanted to just get the total stock on hand for each item then group the data:
select
[ITEM_PARENT]
,sum([STOCK_ON_HAND]) as [TotalStockOnHand]
from tablename
group by
[ITEM_PARENT]
;

Related

How to query data and its count in multiple range at same time

I have a table like below,
id
number
date
1
23
2020-01-01
2
12
2020-03-02
3
23
2020-09-02
4
11
2019-03-04
5
12
2019-03-23
6
23
2019-04-12
I want to know is that how many times each number appears per year, such as,
number
2019
2020
23
1
2
12
1
1
11
1
0
I'm kinda stuck.. tried with left join or just a single select, but still, cannot figure out how to make it, please help thank you!
SELECT C.NUMBER,
SUM
(
CASE
WHEN C.DATE BETWEEN '20190101'AND '20191231'
THEN 1 ELSE NULL
END
) AS A_2019,
SUM
(
CASE
WHEN C.DATE BETWEEN '20200101'AND '20201231'
THEN 1 ELSE NULL
END
) AS A_2020
FROM I_have_a_table_like_below AS C
GROUP BY C.NUMBER

Keep first record in group and populate rest with Null/0 in SQL?

I have the following table in my database:
date sales
1 2010-12-13 10
2 2010-12-13 10
3 2010-12-13 10
4 2010-12-13 10
5 2010-12-13 10
6 2010-12-14 20
7 2010-12-14 20
8 2010-12-14 20
9 2010-12-14 20
10 2010-12-14 20
Is there a way to attain the first record only and populate the rest with NULL or 0 for the remainder of the group? AS the grouping will be done by date and sales:
For example the intended output is:
date sales
1 2010-12-13 10
2 2010-12-13 0
3 2010-12-13 0
4 2010-12-13 0
5 2010-12-13 0
6 2010-12-14 20
7 2010-12-14 0
8 2010-12-14 0
9 2010-12-14 0
10 2010-12-14 0
So essentially to keep the first record but make the rest of the records in the group be 0 (maybe Null if that is quicker/easier)
The closest i have got to solving this is attaining just the first record through an inner join - but I think a partition over may solve it - just stuck at the moment!
Any help appreciated!
Using SQLite - but also GCP (SQL) is accesible to me
This might work in SQLite:
CASE WHEN id = MIN(id) OVER(PARTITION BY date) THEN sales ELSE 0 END as sales
If it doesn't you can prepare a subquery that has only the min ID per date and join it in:
SELECT
CASE WHEN y.id IS NULL THEN 0 ELSE sales END as sales
FROM
x
LEFT JOIN (SELECT MIN(id) as id FROM x GROUP BY date) y ON x.id= y.id

Flipping array in SQL

My original table looks like:
id, date, 1, 2, 3,
1 1 10 10 10
1 2 20 20 20
1 3 30 30 30
1 4 15 15 15
By running the query:
ARRAY_AGG(STRUCT(1, 2, 3)) OVER (PARTITION BY id ORDER BY date ROWS BETWEEN 2
PRECEDING AND CURRENT ROW)
I get this output
1 2 3
1 10 10 10
2 10 10 10
20 20 20
3 10 10 10
20 20 20
30 30 30
4 20 20 20
30 30 30
15 15 15
I would like the output to be:
1 2 3
1 10 10 10
2 20 20 20
10 10 10
3 30 30 30
20 20 20
10 10 10
4 15 15 15
30 30 30
20 20 20
So bascically, the values that I get in my output are all correct, but I would like order of the output to be flipped. Anyone know how to do that with an array(struct)) type of column?
One option is to reverse the sort order of the window clause, or you could use a simple solution of calling the ARRAY_REVERSE function:
ARRAY_REVERSE(
ARRAY_AGG(STRUCT(col1, col2, col3)) OVER (
PARTITION BY id ORDER BY date
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)
)
Added below for the sake of having reverse the sort order of the window clause option here
ARRAY_AGG(STRUCT(col1, col2, col3)) OVER(
PARTITION BY id ORDER BY date DESC
ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING)

Mean Of Sum Of Upper Rows

I expect someone could help me.
I made a table with some data, no need to know what in particual. I come from this #TempTable1:
WEEK_NUMBER SUM MEAN_OF_SUM
---------------------------------------------------------------------------
1 10
2 20
3 30
4 60
5 30
6 60
7 0
My desired table #TempTable1:
WEEK_NUMBER SUM MEAN_OF_SUM
---------------------------------------------------------------------------
1 10 10 --(10/1)
2 20 15 --(30/2)
3 30 20 --(60/3)
4 60 30 --(120/4)
5 30 30 --(150/5)
6 60 35 --(210/6)
7 0 30 --(210/7)
I tried with sums and expected the group by clause would work, but they do not. Does someone has an idea on how to solve this ?
I think are looking for a cumulative average:
select t.*, avg(sum*1.0) over (order by week_number)
from t;
This doesn't match the last value. I'm guessing that is a typo.

T-SQL recursion

I have a set of data that looks like below
Name Time Perc Group Mode Control Cancelled
A 10:52 10.10 10 0 1 0
B 09:00 10.23 10 1 1 1
C 12:02 12.01 12 0 1 1
D 10:45 12.12 12 1 7 1
E 12:54 12.56 12 1 3 0
F 01:01 13.90 13 0 11 1
G 02:45 13.23 13 1 12 1
H 09:10 13.21 13 1 1 0
I need an output like below;
Group Perc Cancelled
10 20.33 1
12 36.69 2
13 40.34 2
What I'm getting was something like;
Group Perc Cancelled
10 20.33 5
12 36.69 5
13 40.34 5
I don't know what to call this, I have something in my mind to call it like CTE?, but I really can't figure it out.
Here's my source;
SELECT Group, SUM(Perc), Cancelled FROM
(SELECT Group, Perc, (SELECT COUNT(*) FROM tblName WHERE Cancelled=1) AS Cancelled FROM tblName WHERE 1=1 AND Group>=10)dt
GROUP BY Group, Cancelled
From your example, you don't need the nested query, any recursion, etc...
SELECT
Group,
SUM(Perc) AS total_perc,
SUM(cancelled) AS total_cancelled
FROM
tblName
WHERE
1=1
AND Group >= 10
GROUP BY
Group
If you did have some different data, then you might want to use something like...
SUM(CASE WHEN cancelled > 0 THEN 1 ELSE 0 END) AS total_cancelled