Find handicap based on Team Average - oracle

Good Day. I have a new Apex database For a dart league.
I have a lot of work to do! but cant combine (with code - I have the right numbers on the interactive grid by using the sum function) I have the following code and results that work for each player, which I need, But cannot get the summed of average for each player.... this matters when creating a handicap.
select Team, name,
COUNT(WEEK) * 3 GAMES,
sum(game_1) + sum(game_2) + sum(game_3) points,
Round(((sum(game_1) + sum(game_2) + sum(game_3)) / ((COUNT(WEEK) * 3))), 2) Average
from score_tbl
group by Team, name
order by 1
TEAM
NAME
GAMES
POINTS
AVERAGE
1
B Tyler
6
142
23.67
1
Blind
6
108
18
1
Jim V
6
53
8.83
1
KC M
6
82
13.67
2
J Spass
6
102
17
2
Randy B
6
105
17.5
2
Tim Ketz
6
74
12.33
2
Todd Lapan
6
51
8.5
I am trying to figure out the code to sum the Averages for each player by team.
Team Average Handicap
Team 1 64.17
Team 2 55.33
etc..
then, if possible compare those averages to find the highest average. Then take the Highest avg - (each Team) * 90%.

I am trying to figure out the code to sum the Averages for each player by team.
Wrap the expression for generating the average in an analytic SUM for each team partition:
SELECT team,
name,
COUNT(WEEK) * 3 AS games,
SUM(game_1 + game_2 + game_3) AS points,
ROUND(AVG(game_1 + game_2 + game_3) / 3, 2) AS average,
ROUND(SUM(AVG(game_1 + game_2 + game_3) / 3) OVER (PARTITION BY team), 2)
AS total_average
FROM score_tbl
GROUP BY
team, name
ORDER BY
team;
Which, for the sample data:
CREATE TABLE score_tbl(team, name, week, game_1, game_2, game_3) AS
SELECT 1, 'B Tyler', 1, 24, 24, 23 FROM DUAL UNION ALL
SELECT 1, 'Blind', 1, 18, 18, 18 FROM DUAL UNION ALL
SELECT 1, 'Jim V', 1, 9, 8, 9.5 FROM DUAL UNION ALL
SELECT 1, 'KC M', 1, 14, 14, 13 FROM DUAL UNION ALL
SELECT 2, 'J Spass', 1, 17, 17, 17 FROM DUAL UNION ALL
SELECT 2, 'Randy B', 1, 18, 17, 17.5 FROM DUAL UNION ALL
SELECT 2, 'Tim Ketz', 1, 13, 12, 12 FROM DUAL UNION ALL
SELECT 2, 'Todd Lapan', 1, 9, 8, 8.5 FROM DUAL UNION ALL
SELECT 1, 'B Tyler', 1, 24, 24, 23 FROM DUAL UNION ALL
SELECT 1, 'Blind', 1, 18, 18, 18 FROM DUAL UNION ALL
SELECT 1, 'Jim V', 1, 9, 8, 9.5 FROM DUAL UNION ALL
SELECT 1, 'KC M', 1, 14, 14, 13 FROM DUAL UNION ALL
SELECT 2, 'J Spass', 1, 17, 17, 17 FROM DUAL UNION ALL
SELECT 2, 'Randy B', 1, 18, 17, 17.5 FROM DUAL UNION ALL
SELECT 2, 'Tim Ketz', 1, 13, 12, 12 FROM DUAL UNION ALL
SELECT 2, 'Todd Lapan', 1, 9, 8, 8.5 FROM DUAL;
Outputs:
TEAM
NAME
GAMES
POINTS
AVERAGE
TOTAL_AVERAGE
1
B Tyler
6
142
23.67
64.17
1
Blind
6
108
18
64.17
1
Jim V
6
53
8.83
64.17
1
KC M
6
82
13.67
64.17
2
J Spass
6
102
17
55.33
2
Randy B
6
105
17.5
55.33
2
Tim Ketz
6
74
12.33
55.33
2
Todd Lapan
6
51
8.5
55.33
fiddle

Related

Multiple joins display student course name

I have the following setup, which is working perfectly. I am difficulty figuring out the syntax how to display the course name in the output. In my test CASE all the rows should have the value Geometry.
In addition, how could I use rank or rank_dense to limit the output to display only 1 row with the highest average?
CREATE TABLE students(student_id, first_name, last_name) AS
SELECT 1, 'Faith', 'Aaron' FROM dual UNION ALL
SELECT 2, 'Lisa', 'Saladino' FROM dual UNION ALL
SELECT 3, 'Leslee', 'Altman' FROM dual UNION ALL
SELECT 4, 'Patty', 'Kern' FROM dual UNION ALL
SELECT 5, 'Betty', 'Bowers' FROM dual;
CREATE TABLE courses(course_id, course_name) AS
SELECT 1, 'Geometry' FROM dual UNION ALL
SELECT 2, 'Trigonometry' FROM dual UNION ALL
SELECT 3, 'Calculus' FROM DUAL;
CREATE TABLE grades(student_id,
course_id, grade) AS
SELECT 1, 1, 75 FROM dual UNION ALL
SELECT 1, 1, 81 FROM dual UNION ALL
SELECT 1, 1, 76 FROM dual UNION ALL
SELECT 2, 1, 100 FROM dual UNION ALL
SELECT 2, 1, 95 FROM dual UNION ALL
SELECT 2, 1, 96 FROM dual UNION ALL
SELECT 3, 1, 80 FROM dual UNION ALL
SELECT 3, 1, 85 FROM dual UNION ALL
SELECT 3, 1, 86 FROM dual UNION ALL
SELECT 4, 1, 88 FROM dual UNION ALL
SELECT 4, 1, 85 FROM dual UNION ALL
SELECT 4, 1, 91 FROM dual UNION ALL
SELECT 5, 1, 98 FROM dual UNION ALL
SELECT 5, 1, 74 FROM dual UNION ALL
SELECT 5, 1, 81 FROM dual;
/* average grade of each student */
select s.student_id
, s.first_name
, s.last_name
, round(avg(g.grade), 1) as student_avg
from students s
join grades g
on s.student_id = g.student_id
group by s.student_id, s.first_name, s.last_name
ORDER BY avg(g.grade) DESC;
Something like this?
SQL> with temp as
2 (select s.student_id
3 , s.first_name
4 , s.last_name
5 , c.course_name
6 , round(avg(g.grade), 1) as student_avg
7 , rank() over (order by avg(g.grade) desc) rnk
8 from students s join grades g on s.student_id = g.student_id
9 join courses c on c.course_id = g.course_id
10 group by s.student_id, s.first_name, s.last_name, c.course_name
11 )
12 select student_id, first_name, last_name, course_name, student_avg
13 from temp
14 where rnk <= 3
15 order by rnk;
STUDENT_ID FIRST_ LAST_NAM COURSE_NAME STUDENT_AVG
---------- ------ -------- ------------ -----------
2 Lisa Saladino Geometry 97
4 Patty Kern Geometry 88
5 Betty Bowers Geometry 84.3
SQL>

Sum a column based on max date and unique range

Basically, trying to figure out how I can Sum the totals column based on the latest/max date, by town, ie filtered by unique and the latest date for each row.
Date
Town
Totals
September 5
Loerie
9
November 8
Loerie
4
May 7
Flower
2
February 2
Holo
8
May 9
Holo
7
July 23
Flower
3
June 7
Dump
1
March 3
Tzaneen
9
September 2
Tzaneen
4
April 3
Coffee
7
Able to unique sort the town list, and show the totals for each based on max date with =maxifs(C$2:C,B$2:B,F2,A$2:A,maxifs(A$2:A,B$2:B,F2))
Need to be able to sort and sum those results in a single function, but unsure how. Arrayformula?
Shared the example doc.
https://docs.google.com/spreadsheets/d/1SSNJJOoz1-pxVH0ZoFFZqChhZxjqtRz5dfvyQu76ueI/edit?usp=sharing
try:
=QUERY(SORTN(SORT(A2:C, 2, 1, 1, 0), 9^9, 2, 2, 1), "select Col2,Col3")
with total:
={QUERY(SORTN(SORT(A2:C, 2, 1, 1, 0), 9^9, 2, 2, 1), "select Col2,Col3");
"Total:", SUM(INDEX(SORTN(SORT(A2:C, 2, 1, 1, 0), 9^9, 2, 2, 1),,3))}
only total:
=SUM(INDEX(SORTN(SORT(A2:C, 2, 1, 1, 0), 9^9, 2, 2, 1),,3))

LISTAG function in oracle giving duplicate values

I have two tables User_details and Level_details.
User_details table:
ID Name
1 A
2 B
3 C
4 D
5 E
Level_details table:
trns_id Lvl usr_id
66 1 1
66 1 5
77 1 2
77 2 3
66 2 4
66 2 3
77 2 3
66 2 4
I am getting the result like:
trns_id Lvl name
66 1 A, E
66 2 D, C, D
77 1 B
77 2 C, C
I am using LISTAG function to get name
LISTAGG(( SELECT name FROM User_details l WHERE l.usr_id = id and trns_id=t1.trns_id and lvl=t1.lvl ), ',') WITHIN GROUP( ORDER BY lvl ) AS Name
You can use the distinct modifier in a listagg function call:
SELECT trns_id, lvl, LISTAGG(DISTINCT name, ', ') WITHIN GROUP (ORDER BY name)
FROM level_details l
JOIN user_details u ON l.usr_id = u.id
GROUP BY trns_id, lvl
If your database version doesn't support DISTINCT within LISTAGG, then you'll have to first select distinct values (lines #21 - 23), then aggregate them (line #20). Lines #1 - 17 represent sample data; you already have that and don't type it. Query you need begins at line #18.
SQL> with user_details (usr_id, name) as
2 (select 1, 'A' from dual union all
3 select 2, 'B' from dual union all
4 select 3, 'C' from dual union all
5 select 4, 'D' from dual union all
6 select 5, 'E' from dual
7 ),
8 level_details (trns_id, lvl, usr_id) as
9 (select 66, 1, 1 from dual union all
10 select 66, 1, 5 from dual union all
11 select 77, 1, 2 from dual union all
12 select 77, 2, 3 from dual union all
13 select 66, 2, 4 from dual union all
14 select 66, 2, 3 from dual union all
15 select 77, 2, 3 from dual union all
16 select 66, 2, 4 from dual
17 )
18 select x.trns_id,
19 x.lvl,
20 listagg(x.name, ', ') within group (order by x.lvl) name
21 from (select distinct u.usr_id, u.name, d.trns_id, d.lvl
22 from user_details u join level_details d on d.usr_id = u.usr_id
23 ) x
24 group by x.trns_id,
25 x.lvl;
TRNS_ID LVL NAME
---------- ---------- ---------------
66 1 A, E
66 2 C, D
77 1 B
77 2 C
SQL>
LISTAGG gives duplicate values if you have duplicate values
trns_id Lvl usr_id
77 2 3
77 2 3
You can remove duplicates first:
select trns_id, Lvl, LISTAGG(name)
from (
select distinct l.trns_id l.Lvl, u.name
from User_details u
join Level_details l on l.usr_id=u.ID
)
group by trns_id, Lvl

Fetch recursive tree with only certain elements "expanded"

We have a table with a self-referencing tree structure (id, parent_id). Let's assume the following tree structure:
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
I'd like to fetch this data for displaying it in a tree. But only certain records expanded. I'm currently using the following query:
SELECT ID, NAME "PATH"
FROM GROUPS
WHERE PRIOR ID IN(1, 4)
CONNECT BY PARENT_ID = PRIOR ID
START WITH PARENT_ID IS NULL;
This works very well and returns the following records:
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
The problem is that this query returns every record of which the direct parent is expanded, but not the whole parent chain. So if we're just expanding id 4, records 5, 6, 7 still shouldn't be returned as 1 is not expanded.
What I have been trying so far is to fetch a custom column which indicates whether the element is expanded, which computes out of whether it is explicitly expanded AND the parent is expanded as well.
SELECT ...
CASE WHEN (ID IN (4) AND PRIOR EXPANDED = 1) THEN 1 ELSE 0 end "EXPANDED"
...
WHERE "EXPANDED" = 1
This does not work as I can use the EXPANDED alias neither in the WHERE statement nor the PRIOR EXPANDED statement.
Is there a simple way of achieving this using a simple query?
Oracle Setup:
CREATE TABLE hierarchy ( id, parent_id ) AS
SELECT 1, NULL FROM DUAL UNION ALL
SELECT 2, 1 FROM DUAL UNION ALL
SELECT 3, 2 FROM DUAL UNION ALL
SELECT 4, 1 FROM DUAL UNION ALL
SELECT 5, 4 FROM DUAL UNION ALL
SELECT 6, 5 FROM DUAL UNION ALL
SELECT 7, NULL FROM DUAL UNION ALL
SELECT 8, 7 FROM DUAL UNION ALL
SELECT 9, 8 FROM DUAL UNION ALL
SELECT 10, 9 FROM DUAL UNION ALL
SELECT 11, 8 FROM DUAL;
Query - IN clause has all parents explanded:
SELECT LPAD( '+ ', LEVEL*2, ' ' ) || id
FROM hierarchy
START WITH parent_id IS NULL
CONNECT BY PRIOR id = parent_id
AND parent_id IN ( 1, 2, 4, 5, 7, 8, 9 );
Output:
+ 1
+ 2
+ 3
+4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
Query - IN clause has all parents expanded except 4 and 8:
SELECT LPAD( '+ ', LEVEL*2, ' ' ) || id
FROM hierarchy
START WITH parent_id IS NULL
CONNECT BY PRIOR id = parent_id
AND parent_id IN ( 1, 2, 5, 7, 9 );
Output:
+ 1
+ 2
+ 3
+4
+ 7
+ 8
Update - Showing leaf nodes:
SELECT LPAD( '+ ', LEVEL*2, ' ' ) || id AS value,
isleaf
FROM (
-- Find the leaves first (as if all parents are expanded)
SELECT h.*,
CONNECT_BY_ISLEAF AS isLeaf
FROM hierarchy h
START WITH parent_id IS NULL
CONNECT BY PRIOR id = parent_id
)
START WITH parent_id IS NULL
CONNECT BY PRIOR id = parent_id
AND parent_id IN ( 1, 2, 4, 7, 9 );
Output:
VALUE ISLEAF
---------------- ----------
+ 1 0
+ 2 0
+ 3 1
+ 4 0
+ 5 0
+ 7 0
+ 8 0
1 Indicates that the node has no children and 0 indicates that the node has children (even though they might not be expanded).
OK, just saw your note about requiring the entire parent chain to be expanded. The following does this by using sys_connect_by_path to build that chain, then checking that it is all 1's (have to lop off the last node which is at the current level):
With 1 and 4 expanded you get:
WITH hier as (
SELECT 1 id, NULL parent_id, 1 expanded FROM DUAL UNION ALL
SELECT 2, 1, 0 FROM DUAL UNION ALL
SELECT 3, 2, 0 FROM DUAL UNION ALL
SELECT 4, 1, 1 FROM DUAL UNION ALL
SELECT 5, 4, 0 FROM DUAL UNION ALL
SELECT 6, 4, 0 FROM DUAL UNION ALL
SELECT 7, 4, 0 FROM DUAL UNION ALL
SELECT 8, 1, 0 FROM DUAL UNION ALL
SELECT 9, 1, 0 FROM DUAL UNION ALL
SELECT 10, 9, 0 FROM DUAL UNION ALL
SELECT 11, 9, 0 FROM DUAL )
SELECT LPAD( '+ ', lvl*2, ' ' ) || id
FROM (
SELECT ID
, parent_id
, level as lvl
, sys_connect_by_path(expanded,'-') as path_expanded
FROM hier
CONNECT BY PARENT_ID = PRIOR ID
START WITH PARENT_ID IS NULL
)
WHERE --every node in the path from the parent is expanded.
instr(substr(path_expanded,1,length(path_expanded)-2),'0') = 0
OR parent_id is null ;
LPAD('+',LVL*2,'')||ID
+ 1
+ 2
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
Change to un-expand at node 1 and you get:
WITH hier as (
SELECT 1 id, NULL parent_id, 0 expanded FROM DUAL UNION ALL
SELECT 2, 1, 0 FROM DUAL UNION ALL
SELECT 3, 2, 0 FROM DUAL UNION ALL
SELECT 4, 1, 1 FROM DUAL UNION ALL
SELECT 5, 4, 0 FROM DUAL UNION ALL
SELECT 6, 4, 0 FROM DUAL UNION ALL
SELECT 7, 4, 0 FROM DUAL UNION ALL
SELECT 8, 1, 0 FROM DUAL UNION ALL
SELECT 9, 1, 0 FROM DUAL UNION ALL
SELECT 10, 9, 0 FROM DUAL UNION ALL
SELECT 11, 9, 0 FROM DUAL )
SELECT LPAD( '+ ', lvl*2, ' ' ) || id
FROM (
SELECT ID
, parent_id
, level as lvl
, sys_connect_by_path(expanded,'-') as path_expanded
FROM hier
CONNECT BY PARENT_ID = PRIOR ID
START WITH PARENT_ID IS NULL
)
WHERE --every node in the path from the parent is expanded.
instr(substr(path_expanded,1,length(path_expanded)-2),'0') = 0
OR parent_id is null ;
LPAD('+',LVL*2,'')||ID
+ 1

transpose row into a single column with pivot or decode in dual table - Oracle

If i give this query,
Select 1,2,3,4,5,6,7,8,9 from dual;
It will look like this
1 2 3 4 5 6 7 8 9 - column names
1 2 3 4 5 6 7 8 9 - Associated values
But i want to show like this
1
2
3
4
5
6
7
8
9
I don't know how to do this with dual table
"Unpivot version":
select val from (select 1, 2, 3, 4, 5, 6, 7, 8, 9 from dual)
unpivot (val for tmp in ("1", "2", "3", "4", "5", "6", "7", "8", "9"))
Simpler alternative giving the same results:
select * from table(sys.odcinumberlist(1, 2, 3, 4, 5, 6, 7, 8, 9))
Just use union all:
select 1 as name from dual union all
select 2 as name from dual union all
select 3 as name from dual union all
select 4 as name from dual union all
select 5 as name from dual union all
select 6 as name from dual union all
select 7 as name from dual union all
select 8 as name from dual union all
select 9 as name from dual;

Resources