Flipping array in SQL - 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)

Related

Cumulative sum in SQL using window function

QTY
STOCK
RNK
ID KEY
CUM SUM
40
35
1
1
35
20
35
2
1
0
15
35
3
1
0
58
35
4
1
0
18
35
5
1
0
40
35
1
2
35
20
35
2
2
0
15
35
3
2
0
CUM SUM should be MIN(QTY, STOCK-SUM(all rows in cumsum before the current row)) for every other row and for 1st row it should be MIN(QTY, STOCK-SUM(0))=> MIN(QTY,STOCK)
QTY
STOCK
RNK
ID KEY
CUM SUM
40
35
1
1
5
20
35
2
1
-10
15
35
3
1
-30
58
35
4
1
-7
18
35
5
1
-24
40
35
1
2
5
20
35
2
2
-10
15
35
3
2
-30
After, I tried I am getting the above output
SELECT sum(qty-stock) over (
partition by ID KEY
ORDER BY rnk
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) as CUM SUM
FROM TABLE
Need to get correct cumsum value using a window function in the existing table
You may use a rolling SUM() here, using SUM() as an analytic function:
SELECT *, SUM(QTY - STOCK) OVER (PARTITION BY ID_KEY ORDER BY RNK) AS CUM_SUM
FROM yourTable
ORDER BY ID_KEY, RNK;

How to do calculate recursive sum in SQL in configurable in Big Query

I have query problem, I'm using Google BigQuery (Just to give you context if it is different). I need two value which is Value_A and Value_B. Value_A is top X value, and Value_B is the rest of top X value.Here's my Input Table
Date Value
20 10
19 10
18 10
17 10
16 10
15 10
14 10
13 10
12 10
11 10
10 10
9 10
8 10
7 10
6 10
5 10
4 10
3 10
2 10
1 10
In this case, the value of X is 6, but I need to be configurable.
In date 20, Value_A is sum from the 6 top data in Value (which is date 14 to 20), and Value_B is sum of rest of top data (which is date 14 an below).
In date 19, Value_A is sum from the 6 top data in Value (which is date 13 to 19), and Value_B is sum of rest of top data (which is date 13 an below).
Here's my output
Date Value Value_A Value_B
20 10 60 140
19 10 60 130
18 10 60 120
17 10 60 110
16 10 60 100
15 10 60 90
14 10 60 80
13 10 60 70
12 10 60 60
11 10 60 50
10 10 60 40
9 10 60 30
8 10 60 20
7 10 60 10
6 10 60 0
5 10 50 0
4 10 40 0
3 10 30 0
2 10 20 0
1 10 10 0
Below is for BigQuery Standard SQL
#standardSQL
SELECT date, value,
SUM(value) OVER(ORDER BY date DESC ROWS BETWEEN CURRENT ROW AND 5 FOLLOWING) Value_A,
IFNULL(SUM(value) OVER(ORDER BY date DESC ROWS BETWEEN 6 FOLLOWING AND UNBOUNDED FOLLOWING), 0) Value_B
FROM `project.dataset.table`
-- ORDER BY date DESC
If to apply to sample data from your question, as in below example
#standardSQL
WITH `project.dataset.table` AS (
SELECT 20 date, 10 value UNION ALL
SELECT 19, 10 UNION ALL
SELECT 18, 10 UNION ALL
SELECT 17, 10 UNION ALL
SELECT 16, 10 UNION ALL
SELECT 15, 10 UNION ALL
SELECT 14, 10 UNION ALL
SELECT 13, 10 UNION ALL
SELECT 12, 10 UNION ALL
SELECT 11, 10 UNION ALL
SELECT 10, 10 UNION ALL
SELECT 9, 10 UNION ALL
SELECT 8, 10 UNION ALL
SELECT 7, 10 UNION ALL
SELECT 6, 10 UNION ALL
SELECT 5, 10 UNION ALL
SELECT 4, 10 UNION ALL
SELECT 3, 10 UNION ALL
SELECT 2, 10 UNION ALL
SELECT 1, 10
)
SELECT date, value,
SUM(value) OVER(ORDER BY date DESC ROWS BETWEEN CURRENT ROW AND 5 FOLLOWING) Value_A,
IFNULL(SUM(value) OVER(ORDER BY date DESC ROWS BETWEEN 6 FOLLOWING AND UNBOUNDED FOLLOWING), 0) Value_B
FROM `project.dataset.table`
ORDER BY date DESC
result is
Row date value Value_A Value_B
1 20 10 60 140
2 19 10 60 130
3 18 10 60 120
4 17 10 60 110
5 16 10 60 100
6 15 10 60 90
7 14 10 60 80
8 13 10 60 70
9 12 10 60 60
10 11 10 60 50
11 10 10 60 40
12 9 10 60 30
13 8 10 60 20
14 7 10 60 10
15 6 10 60 0
16 5 10 50 0
17 4 10 40 0
18 3 10 30 0
19 2 10 20 0
20 1 10 10 0

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.

table name t 10 20 30 40 want output as 10 30 50 70 in sql

t 10 20 30 40
output 10 30 50 70
One method of doing this is a cumulative sum with a window function:
select col,
sum(col) over (order by col
rows between 1 preceding and current row
)
from t;

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