How do I calculate group subtotals for a specific number of rows in a table - sql

I am really learning a lot here. Thanks to all the support. I have another challenge however.
I want to calculate a weighted Index for a group of rows 'Div' within a particular month as shown below:
Wght tMonth tYear Div Indices
37.5 01 2015 01 157.27
2.7 01 2015 01 127.36
58.7 01 2015 01 142.48
DivIndex 146.11
34.9 01 2015 02 133.33
6.7 01 2015 02 136.49
52.4 01 2015 02 131.34
DivIndex 124.43
43.9 02 2015 01 157.18
44.8 02 2015 01 127.42
DivIndex 126.09
58.7 02 2015 03 145.67
7.5 02 2015 03 134.70
6.7 02 2015 03 137.24
DivIndex 104.72
54.0 03 2015 05 160.61
DivIndex 86.73
48.1 03 2015 04 127.49
58.7 03 2015 04 148.62
DivIndex 148.58
I used Excel to compute the 'DivIndex' and that is what I want to come up with in Sql Server 2008R2.
Thanks in advance for any help.

You can do the calculation as:
select tyear, tmonth,
sum(weight * dev_indices) / sum(weight)
from t
group by tyear, tmonth
order by tyear, tmonth;

Related

SQL - SUM and grouping

I have a following table:
ITEM
Date
VALUE
START DATE
END DATE
1
01 Jan 2023
15
01 Jan 2023
02 Jan 2023
1
02 Jan 2023
20
02 Jan 2023
03 Jan 2023
1
03 Jan 2023
25
03 Jan 2023
04 Jan 2023
1
04 Jan 2023
40
04 Jan 2023
05 Jan 2023
2
01 Jan 2023
30
01 Jan 2023
02 Jan 2023
2
02 Jan 2023
20
02 Jan 2023
03 Jan 2023
2
03 Jan 2023
10
03 Jan 2023
04 Jan 2023
2
04 Jan 2023
40
04 Jan 2023
05 Jan 2023
From here I need to have calculated sum of all values for every given row/date that are within dates in Start and End Date columns (boundaries included), so it is grouped by item and per date.
ITEM
Date
VALUE_SUM
1
01 Jan 2023
35
1
02 Jan 2023
45
1
03 Jan 2023
65
1
04 Jan 2023
40
2
01 Jan 2023
50
2
02 Jan 2023
30
2
03 Jan 2023
50
2
04 Jan 2023
40
Thanks for your help!
A simple way is to use a correlated subquery to do the calculation:
select item, date,
(select sum(value) from table t2
where t2.item = t1.item
and t2.date between t1.start_date and t1.end_date)
from table t1
Assuming you are only working with one month of data - one option could be to extract the day value from each date and then sum up each value while grouping by day.
This can be done by firstly creating a new variable in your dataset to store the day value:
alter table dataset add day int;
Values can then be extracted:
update dataset set day=extract(day from date);
Then, it is a matter of grouping the values by day:
select day, sum(value) as value_sum from dataset group by day order by day;

Making a duplicate row in SQL table based on condition, and replacing a value in the new row

I have a table that looks something like this:
Agency Year Total PopGroup
01 2017 3467 3C
01 2018 3444 3C
01 2019 3567 3C
02 2017 1000 1C
02 2018 1354 1C
02 2019 1333 1C
03 2017 6784 2C
03 2018 3453 2C
04 2017 3333 2C
If an agency has a row for year 2019, I want to duplicate this row and call it 2020 (basically, an estimate population for 2020). Desired result:
Agency Year Total PopGroup
01 2017 3467 3C
01 2018 3444 3C
01 2019 3567 3C
01 2020 3567 3C
02 2017 1000 1C
02 2018 1354 1C
02 2019 1333 1C
02 2020 1333 1C
03 2017 6784 2C
03 2018 3453 2C
04 2017 3333 2C
I think I should use something like:
INSERT INTO table
WHERE Year = 2019
but I'm a little stuck. What can I try next?
You are on the right track:
INSERT INTO table (Agency, Year, Total, PopGroup)
SELECT Agency, 2020 as Year, Total, PopGroup
FROM table t
WHERE Year = 2019 ;
you can use the following insert to add a new row exactly same as another one but with some modified data.
insert into table (select agency, 2020, total, popgroup from table where year = 2019)
this will insert a new record exactly same as 2019 but with year 2020

How to generate repeating numbers in sequence

I would like to generate this sequence
col sequence
01 01
01 02
01 03
01 04
01 05
02 01
02 02
02 03
02 04
02 05
..
..
12 01
12 02
12 03
12 04
12 04
And add this as a sequence to another select.
Hierarchical query might help to produce result you posted:
SQL> with
2 c1 as
3 (select lpad(1 + level - 1, 2, '0') col1
4 from dual
5 connect by level <= 12
6 ),
7 c2 as
8 (select lpad(1 + level - 1, 2, '0') col2
9 from dual
10 connect by level <= 5
11 )
12 select c1.col1, c2.col2
13 from c1 cross join c2
14 order by c1.col1, c2.col2;
CO CO
-- --
01 01
01 02
01 03
01 04
01 05
02 01
02 02
02 03
02 04
02 05
03 01
03 02
<snip>
11 04
11 05
12 01
12 02
12 03
12 04
12 05
60 rows selected.
SQL>
You want row_numner() :
select col, row_number() over (partition by col order by col) as sequence
from table t;
You can use sub-query for further operation.

How to limit max rows in select query by key

I have
ID ID2 Amount
-------- -------- ------
01 02 20
01 03 30
02 04 40
02 06 30
03 05 70
03 06 60
03 07 60
04 08 100
04 09 110
I want to query the data above into 2 resultset (return max 5 rows) which are:
result 1:
ID1 ID2 Amount
-------- -------- ------
01 02 20
01 03 30
02 04 40
02 06 30
result 2:
ID1 ID2 Amount
-------- -------- ------
03 05 70
03 06 60
03 07 60
04 08 100
04 09 110
How should I construct my query?
use row_number() to generate a sequential no. (row_number() over (order by ID1) - 1) / 5 + 1 will gives you set of 5 per each result
; WITH CTE AS
(
SELECT result_no = (row_number() over (order by ID1) - 1) / 5 + 1,
ID1, ID2, Amount
FROM yourtable
)
SELECT *
FROM CTE
WHERE result_no = #result_no

ROLLUP function in SQL

In my line of work, rollup refers to combining/averaging months or quarters. In this case, the rollup is based on INDCODE and PERIOD. I have a table named INDUSTRY that contains data from quarters 1, 2, 3, and 4. Below is a sample of what it looks like.
State area periodyear period indcode firms avgemp
32 000001 2016 01 447125 25 412
32 000001 2016 02 447125 28 427
32 000001 2016 03 447125 29 429
32 000001 2016 04 447125 26 385
First, I am trying to average certain fields but not all. In this case, it would be firms and avgemp. If I was wanting it to look like the desired result below, can I use the rollup function? I want the new averaged data to be in the same table as quarters 1, 2, 3, and 4. Is it better to put the averaged data in a new table?
State area periodyear period indcode firms avgemp
32 000001 2016 01 447125 25 412
32 000001 2016 02 447125 28 427
32 000001 2016 03 447125 29 429
32 000001 2016 04 447125 26 385
32 000001 2016 00 447125 27 413