Lab 5 – aggregation, functions dates, strings
Sysdate – current date/time
2
• Sysdate – variable -> returns days!
• If have variable which is date of birth, can calculate age:• Sysdate – dob = age in days
Functions – loads of them! http://download.oracle.com/docs/cd/
B19306_01/server.102/b14200/functions001.htm#i88893
Functions have at least two pieces function name Open parenthenses The argument(s) passed, normally
separated by commas Sometimes there may be no argument so
this is empty Closing parentheses
5
String function
Upper -> returns the upper case of the argument (string) passed Upper(name)
Lower -> returns the lowercase of the argument (string) passed Lower(name)
Length -> returns the length of a string Length(name)
6
To make proper name
Fname || ‘ ‘ ||Lname
You can add any constants in between the pipe operators.
i.e. bride_fname || ‘ and her lovely groom’ ||groom_fname
8
Math functions
Round– rounds up or down at the specified number of decimal points Round(n, precision) Try this:
Select (sysdate - appt_date) from vet_appt;
Now round to two decimal places: Select round((sysdate - appt_date), 2) from
vet_appt;
9
Math functions - Trunc
Trunc – truncates at the specified number of decimal points Trunc(n, precision) Select trunc((sysdate - appt_date), 2) from
vet_appt;
Write one query with both – any differences? Select trunc((sysdate - appt_date), 2),
round((sysdate - appt_date), 2) from vet_appt;
10
Aggregation functions
Return only 1 row as an output. The output displays the
mathematical result of one of the following 5 functions: Min Max Avg Sum count
11
12
Aggregate Function OperationsMin, Max, Avg
Function
? Example
Min What’s the least, lowest
Select min(temperature) from vet_apptWhere animal_id =1
Max What’s the highest, most
Select min(temperature) from vet_apptWhere animal_id =1
Avg What’s the average
Select avg(temperature)from vet_apptWhere animal_id =1
13
Aggregate Function OperationsSum, Count
Function
? Example
Sum What’s the total
Select sum(weight) from vet_appt
Count How many Select count(vet_client_id)From vet_client
Distinct Count
Shows the unique number
Select count(distinct(breed)) From animal;
Compare this to:count(breed)From animal;
Rules on Aggregation Can have multiple aggregated
functions (avg(weight), min(weight), max(weight) ) in one query
SQL> Select avg(weight), min(weight), max(weight)
2 From vet_appt, animal, 3 Where animal.breed = 1 and 4 Vet_Appt.animal_id = animal.animal_id;AVG(WEIGHT) MIN(WEIGHT) MAX(WEIGHT)----------- ----------- ----------- 79.0625 79 79.25
14
Aggregation rules, contd.CANNOT have aggregated function (avg, min, max, sum, count) in same select query as non-aggregated data (breed)
SQL> Select breed, avg(weight), min(weight), max(weight)
2 From vet_appt, animal 3 Where animal.breed = 1 and 4 Vet_Appt.animal_id = animal.animal_id;Select breed, avg(weight), min(weight), max(weight) *ERROR at line 1:ORA-00937: not a single-group group function
15
Group by
What if you want to have your output subsorted ?
What is the average weight by breed?
You need a group by!!!
16
Group by
Select avg(weight)From vet_appt, animalWhere vet_appt.animal_id =
animal.animal_id; AVG(WEIGHT)----------- 25.3938596
17
Wait – this is just one row – I want to see it by breed!Select avg(weight)From vet_appt,
animalWhere
vet_appt.animal_id = animal.animal_id
Group by breed;
18
AVG(WEIGHT)----------- 79.0625 15.8596154 13.925 50.225 9.05 34.6666667
6 rows selected.
Can I add breed to my output? – YES since you GROUPED it!!!
Select breed, avg(weight)
From vet_appt, animal
Where vet_appt.animal_id = animal.animal_id
Group by breed; 19
BREED AVG(WEIGHT)---------- ----------- 1 79.0625 8 15.8596154 9 13.925 13 50.225 14 9.05 15 34.6666667
6 rows selected.
Can I add the breed description instead?Select breed_description, avg(weight)From vet_appt, animal, breedWhere vet_appt.animal_id =
animal.animal_id and breed = breed_id
Group by breed_description;
20
The group by indicates on which variable you are creating the distribution. This needs to be the SAME
attribute as in the select statement
Output with breed_descriptionBREED_DESCRIPTION AVG(WEIGHT)
-------------------------------------------------- -----------
Domestic Long Hair 13.925
Domestic Short Hair 15.8596154
Hemingway Polydactyl 9.05
Mixed 50.225
Siberian Husky 79.0625
Southdown Babydoll 34.6666667
6 rows selected.
21
How about an alias and round?Select breed_description as
“Breed”, round(avg(weight),2) as “Average Weight”
From vet_appt, animal, breedWhere vet_appt.animal_id =
animal.animal_id and breed = breed_id
Group by breed_description;
22
Output with rounding and aliasBreed Average Weight
-------------------------------------------------- --------------
Domestic Long Hair 13.93
Domestic Short Hair 15.86
Hemingway Polydactyl 9.05
Mixed 50.23
Siberian Husky 79.06
Southdown Babydoll 34.67
6 rows selected.
23
Can I add a filter?
Select breed_description as “Breed”, round(avg(weight),2) as “Average Weight”
From vet_appt, animal, breedWhere vet_appt.animal_id =
animal.animal_id and breed = breed_id and
Breed = 15Group by breed_description;
24
Sure… here’s with a filterBreed
Average Weight--------------------------------------------------
--------------Southdown Babydoll
34.67
25
Can I filter on my aggregation?Select breed_description as “Breed”,
round(avg(weight),2) as “Average Weight”
From vet_appt, animal, breedWhere vet_appt.animal_id =
animal.animal_id and breed = breed_id andavg(weight) > 30
Group by breed_description; 26
Ooops….
ERROR at line 5:ORA-00934: group function is not allowed here
27
To filter on aggregated data (such as using the function
average, min, max, min, sum in your filter) MUST have a
HAVING clause
Consider this query:
Select breed_description as “Breed”, round(avg(weight),2) as “Average Weight”
From vet_appt, animal, breedWhere vet_appt.animal_id =
animal.animal_id and breed = breed_id
Group by breed_description;;
29
Here’s the output
Breed Average Weight
-------------------------------------------------- --------------
Domestic Long Hair 13.93
Domestic Short Hair 15.86
Hemingway Polydactyl 9.05
Mixed 50.23
Siberian Husky 79.06
Southdown Babydoll 34.67
6 rows selected.
30
But what if I only want those with the average weight > 30 - Adding HavingSelect breed_description as “Breed”,
round(avg(weight),2) as “Average Weight”
From vet_appt, animal, breedWhere vet_appt.animal_id =
animal.animal_id and breed = breed_id
Group by breed_description
Having avg(weight) > 30 ; 31
Here’s the new output – 3 less recordsBreed
Average Weight--------------------------------------------------
--------------Mixed
50.23Siberian Husky
79.06Southdown Babydoll
34.6732
Can you have aggregated and unaggregated filters in the same query?
Select breed_description as “Breed”, round(avg(weight),2) as “Average Weight”
From vet_appt, animal, breed
Where vet_appt.animal_id = animal.animal_id and
breed = breed_id and
primary_color >3
Group by breed_description
Having avg(weight) >30;
33
The whole shebang
Select client_lname, name, count(vet_appt.appt_id) as “Appt count”
From animal, vet_client, vet_apptWhere vet_client.client_id = animal.client_id
andVet_appt.animal_id = animal.animal_id and
Dob >to_date( ‘01/01/1986’, ‘MM/DD/YYYY’)
Group by client_lname, nameHaving count(animal.animal_id) >=1Order by client_lname asc, name asc;
34