My data is as follows:
QUARTER_CMT DEPT SALES
7 A 39
8 A 23
9 A 33
10 A 45
11 A 50
12 A 110
1 B 44
2 B 56
3 B 87
4 B 22
I am aiming at getting total SALES for every 4 quarters by DEPT and retain Quarter_CNT number as a rollup.
QUARTER_CMT DEPT SALES_TOT
7 A 140
11 A 160
1 B 209
Work in progress code. I thought to sub-group totals and join to latest QUARTER_CMT to have one row by DEPT :
SELECT
ROW_NUMBER() OVER(PARTITION BY DEPTORDER BY QUARTER_CMT) as RN,
QUARTER_CMT,
DEPT,
--RANK() OVER(PARTITION BY ODDZIAL ORDER BY QUARTER_COUNT) AS RowNumberRankOrg,
--NTILE(4) OVER(PARTITION BY ODDZIAL ORDER BY QUARTER_COUNT) AS RowNumberRank,
SALES
FROM TABLE_1
ORDER BY DEPT, QUARTER_CMT
Try this:
with a as (
select
row_number() over(partition by dept order by quarter_cmt)-1 n,
quarter_cmt, dept, sales
from t
order by dept, quarter_cmt
)
select min(quarter_cmt) quarter_cmt, dept, sum(sales) sales_tot
from a
group by dept, floor(n/4)
order by dept, quarter_cmt
;
Assuming this sample data:
create or replace table t as
select $1 QUARTER_CMT, $2 DEPT, $3 SALES from values
(7,'A',39),
(8,'A',23),
(9,'A',33),
(10,'A',45),
(11,'A',50),
(12,'A',110),
(1,'B',44),
(2,'B',56),
(3,'B',87),
(4,'B',22)
;
you need to divide row_number to 5 for determine the periods
SELECT MIN (QUARTER_CMT) QUARTER_CMT, DEPT, SUM(SALES) SALES, PART
FROM (
SELECT *, FLOOR(ROW_NUMBER() OVER(PARTITION BY DEPT ORDER BY QUARTER_CMT) / 5) AS PART
FROM TABLE_1
) AS T
GROUP BY DEPT, PART
ORDER BY DEPT, PART
Result:
QUARTER_CMT DEPT SALES PART
----------- ---- ----------- -----------
7 A 140 0
11 A 160 1
1 B 209 0
Related
I am having some trouble with the below query. I do understand I need to group by ID and Category, but I only want to group by ID while keeping the rest of the columns based on Rank being max. Is there a way to only group by certain columns?
select ID, Category, max(rank)
from schema.table1
group by ID
Input:
ID Category Rank
111 3 4
111 1 5
123 5 3
124 7 2
Current Output
ID Category Rank
111 3 4
111 9 1
123 5 3
124 7 2
Desired Output
ID Category Rank
111 1 5
123 5 3
124 7 2
You can use:
select *
from table1
where (id, rank) in (select id, max(rank) from table1 group by id)
Result:
ID CATEGORY RANK
---- --------- ----
111 1 5
123 5 3
124 7 2
Or you can use the ROW_NUMBER() window function. For example:
select *
from (
select *,
row_number() over(partition by id order by rank desc) as rn
from table1
) x
where rn = 1
See running example at db<>fiddle.
You can try using - row_number()
select * from
(
select ID, Category,rank, row_number() over(partition by id order by rank desc) as rn
from schema.table1
)A where rn=1
How to get the max value order of each customer ?
select num, max(sum(paid*quantity))
from orders join
pizza
using (order#)
group by customer#;
table
num orderN price
-------- --- -------
1 109 30
1 118 25
3 101 30
3 115 27
4 107 23
5 100 17
5 129 16
output req-
num Pnum price
-------- --- -------
1 109 30
3 101 30
4 107 23
5 100 17
You want to select the record having the highest price in each group of nums.
If your RDBMS supports window functions, that's straight forward with ROW_NUMBER() :
SELECT num, pnum, price
FROM (
SELECT t.*, ROW_NUMBER OVER(PARTITION BY num ORDER BY price DESC) rn
FROM mytable t
) x
WHERE rn = 1
Else, you can take the following approach, that uses a NOT EXISTS condition with a correlated subquery to ensure that the record being joined in the one with the highest price for the current num :
SELECT num, pnum, price
FROM mytable t
WHERE NOT EXISTS (
SELECT 1 FROM mytable t1 WHERE t1.num = t.num AND t1.price > t.price
)
I am using SQL Server 2008 R2 and have a structure as below:
create table #temp( deptid int, regionid int)
insert into #temp
select 15000, 50
union
select 15100, 51
union
select 15200, 50
union
select 15300, 52
union
select 15400, 50
union
select 15500, 51
union
select 15600, 52
select deptid, regionid, RANK() OVER(PARTITION BY regionid ORDER BY deptid) AS 'RANK',
ROW_NUMBER() OVER(PARTITION BY regionid ORDER BY deptid) AS 'ROW_NUMBER',
DENSE_RANK() OVER(PARTITION BY regionid ORDER BY deptid) AS 'DENSE_RANK'
from #temp
drop table #temp
And output currently is as below:
deptid regionid RANK ROW_NUMBER DENSE_RANK
--------------------------------------------------
15000 50 1 1 1
15200 50 2 2 2
15400 50 3 3 3
15100 51 1 1 1
15500 51 2 2 2
15300 52 1 1 1
15600 52 2 2 2
My requirement however is to row_number over regionid column but by grouping and not row by row. To explain better, below is my desired result set.
deptid regionid RN
-----------------------
15000 50 1
15200 50 1
15400 50 1
15100 51 2
15500 51 2
15300 52 3
15600 52 3
Please let me know if my question is unclear. Thanks.
Use dense_rank() over (order by regionid) to get the expected result.
select deptid, regionid,
DENSE_RANK() OVER( ORDER BY regionid) AS 'DENSE_RANK'
from #temp
Partitioning within a rank/row_number window function will assign numbers within the partitions, so you don't need to use a partition on regionid to order the regionids themselves.
With the results of Loc_1 query below, I would like to include the top row balance field 100.
select AVG(Age) as AvgAge , Balance as BalanceLeft from
(
select top(5)* from Employee
where LocationID=1
order by HireDate desc
) as Loc_1
Age HireDate LocationID Balance
30 10-12-2014 1 100
20 09-12-2014 1 200
40 08-12-2014 1 300
50 07-12-2014 1 400
20 06-12-2014 1 500
Results
AvgAge Balanceleft
32 100
i just want to include just the top row column balance i.e 100
You can use conditional aggregation, if I understand the question correctly:
select AVG(Age) as AvgAge,
max(case when seqnum = 1 then Balance end) as BalanceLeft
from (select top(5) e.*,
row_number() over (order by hiredate desc) as seqnum
from Employee e
where LocationID=1
order by HireDate desc
) Loc_1
How to find sum of first three salary where total rows on the table six rows.
id Salary
01 100
02 200
03 300
04 400
05 500
06 600
Try using this.....
SELECT SUM(salary)
FROM
(SELECT
ROW_NUMBER() OVER (ORDER BY id ASC) AS ROW_NUMBER, salary
FROM tablename) AS foo
WHERE
ROW_NUMBER <= 3
Do you mean this:
SELECT SUM(Salary)
FROM (
SELECT Salary FROM your_table ORDER BY id LIMIT 3
) A
Assuming it to be SQL Server:
SELECT SUM(Salary) As SalaryTotal
(
SELECT TOP 3 * FROM your_table ORDER BY ID
)
If you want SUM of highest 3 salaries then you can ORDER BY Salary:
SELECT SUM(Salary) As SalaryTotal
(
SELECT TOP 3 * FROM your_table ORDER BY salary DESC
)